A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

图片上传预览想必大家都能知道,使用form提交就可以把图片进行提交了,但是在现实中这样的操作往往满足不了用户需求,一般在进行上传操作时可能会进行图片的多次重新选择和增删所选择的图片,这时用form提交就实现不了。
这时就该我们本篇的主角闪亮登场了:FormData。
W3C在2008年提出XMLHttpRequest Level 2的草案中改进了XMLHttpRequest对象,在新版本的一些功能中就有FormData。利用FormData对象,我们可以模拟表单操作,然后通过XMLHttpRequest的send()方法来异步提交这个表单,发送FormData对象,这与form提交网页表单的效果完全一样,这个改进使得可以通过新版XMLHttpRequest对象上传文件,使得无刷新上传文件成为了可能。
1.FormData
创建一个FormData对象,可以直接通过new FormData()创建一个FormData空对象:
[JavaScript] 纯文本查看 复制代码
	
var formData = new FormData();

当然,想要构造一个包含Form表单数据的FormData对象时,也可以通过HTML表单创建FormData对象,需要在创建FormData对象时指定表单的元素,这样做在发送数据时会将你的form表单的数据添加到formData中一起发送出去。
[JavaScript] 纯文本查看 复制代码

var myform = document.querySelector("form");
var formData = new FormData(myform);

2.FormData操作方法
FormData通过append(name, value,filename)来添加数据,其实就是类似于使用键值对添加数据,如果添加的name不存在则会新增一条数据,如果name已存在,则value将添加到数组的末尾,类似于[‘a1’,’a2’]。filename是可选的,这是指定文件的文件名,当value参数被指定为一个Blob对象或者一个File对象时,该文件名会被发送到服务器上,对于Blob对象来说,这个值默认为blob。
[JavaScript] 纯文本查看 复制代码
formData.append("a1", "aa");
formData.append("a1", "bb");
formData.append("a1", "cc");
formData.getAll("a1"); // ["aa","bb","cc"]

set(name, value) 方法会对 FormData 对象里的某个 name 设置一个新的value,如果该 name 不存在,则添加。
[JavaScript] 纯文本查看 复制代码
formData.append("a1", "aa");
formData.set("a1","bb");
formData.get("a1"); // "bb"

delete() 方法 会从 FormData 对象中删除指定 name 和它对应的 value。
[JavaScript] 纯文本查看 复制代码
formData.append("a1", "aa");
formData.delete("a1");
formData.get("a1"); ////null

get()和getAll(),get()方法用于返回FormData对象中和指定的键关联的第一个值,getAll()方法会返回该 FormData 对象指定键的所有值。
[JavaScript] 纯文本查看 复制代码
formData.append("a1", "aa");
formData.append("a1", "bb");
formData.append("a1", "cc");
formData.get("a1"); // "aa"
formData.getAll("a1"); // ["aa","bb","cc"]

has()方法会返回一个布尔值,表示该FormData对象是否含有某个name 。
[JavaScript] 纯文本查看 复制代码
formData.append("a1", "aa");
formData.has("a1");  //true

当然还有遍历,entries()遍历所有的数据,keys()遍历所有key,values()遍历所有value,用法都一样
[JavaScript] 纯文本查看 复制代码
formData.append('a', 'aa');
formData.append('b', 'bb');
for(var pair of formData.entries()) {     
   console.log(pair[0]+ ', '+ pair[1]);   //a,aa   
}                                         //b,bb

好了,废话说了这么多,该进入正题了。
想要对用户选择的图片进行准确的上传,用什么方式最简单呢?当然是用数组进行操作啦。
首先来个上传多文件上传input
[XHTML] 纯文本查看 复制代码
<input type="file" class="hidden"  id="file"  multiple="multiple"/>

然后声明一个空数组,在onchang事件发生时把用户要上传的图片装进去
[JavaScript] 纯文本查看 复制代码
var filearr = [];
var myfile = document.getElementById('file');
myfile.onchange = function(){
	var files = this.files; 
	if(!files.length)return;
	for(var i = 0;i<files.length;i++){				
		 filearr.push(files[i]);
		 //这里就进行添加图片的预览操作 	
	}
}

当用户删除图片时(.close是删除按钮,closeli()是.close点击时执行的函数),filearr也进行删除,预览用的图片也要干掉,当然数据结构不同时自行处理
[JavaScript] 纯文本查看 复制代码
<li><img src=""><span class="close">×</span></li>
var closes = document.getElementsByClassName("close");
function closeli(obj){
	var closes = document.getElementsByClassName("close");
	[].slice.call(closes).forEach(function(el,index){
		if(obj === closes[index]){
			filearr.splice(index,1);
		};
	});				
	parents(obj,'li').remove();
}
function parents(obj,node){					
	if(obj.parentNode.tagName==node.toUpperCase()){
		return obj.parentNode;
	}else{
		return  parents(obj.parentNode,node);					
	}				
}

点击上传时,如果要连form表单中的数据一起提交就把form传入FormData中,否则可以创建一个FormData空对象提交,当然你也可以通过append添加自定义数据。
[JavaScript] 纯文本查看 复制代码
function sub(){		
    var myform = document.querySelector("form");		
	var formData = new FormData(myform);				
	for(var i =0;i<filearr.length;i++){    //提交时,我们把filearr中的数据遍历一遍
		formData.append("upfile[]", filearr[i]); //用append添加到formData中,就得用户最终要提交的图片了	
	};
	formData.append("aaa", 111);	
	var request = new XMLHttpRequest(); 				
	request.open("POST", "1.php",true);
	request.onreadystatechange = function(){					
		if(request.readyState==4){						
			
		}
	};                          //注意一定不要设置request.setRequestHeader
	request.send(formData);
}

可以用1.php看看上传的数据
[PHP] 纯文本查看 复制代码
<?php
var_dump($_FILES);     //上传的图片
var_dump($_REQUEST);   //上传的数据
?>

php接收的数据
当然,你如果用的是jq的话,ajax得改一改。processData设置为false,因为data值是FormData对象,不需要对数据做处理;contentType设置为false,因为上传的是FormData对象,不需要设置内容类型;当然上传文件不需要缓存,cache:false。
[JavaScript] 纯文本查看 复制代码
function sub(){	
	$.ajax({
		  url: "1.php",
		  type: "POST",
		  data:formData,
		  cache:false,         //不设置缓存
		  processData: false,  // 不处理数据
		  contentType: false   // 不设置内容类型
	});	
}
由于本文在github上的,做不了服务器演示,故不能成功提交,想看提交数据的自行打开浏览器的notwork查看:

ok,图片上传就算是完成了,当然本人原创内容,能力有限,才疏学浅,有错误的地方望大家指正。下次更新文件上传时的一些杂项,比如美化上传按钮,显示上传进度什么的。请期待:请期待:图片上传那些事-总结篇。
本文代码地址:链接

4 个回复

倒序浏览
奈斯
回复 使用道具 举报
回复 使用道具 举报
奈斯
回复 使用道具 举报
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马