XMLHttpRequest Level 2添加了一个新的接口FormData,
利用FormData对象
,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()
方法来异步的提交这个"表单",比起普通的ajax,使用FormData
的最大优点就是我们可以异步上传一个二进制文件。
构造函数:
new FormData(optional HTMLFormElement form)
参数:form(可选)一个HTML表单元素,可以包含任何形式的表单控件,包括文件上传框。
方法:append() 给当前FormD他对象添加一个键值对。
void append(DOMString name,Blob value,optional DOMString filename); void append(DOMString name,DOMString value);
参数值
name:
字段名称.
value:
字段值.可以是,或者一个字符串,如果全都不是,则该值会被自动转换成字符串。
filename:(可选) 指定文件的文件名,当value
参数被指定为一个Blob
对象或者一个File
对象时,该文件名会被发送到服务器上,对于Blob
对象来说,这个值默认为"blob".
利用FormData对象,可以使用一系列的键值对模拟一个完整的表单,然后使用XMLHttpRequest发送这个“表单”。
1、创建一个FormData对象
可以先创建一个空的FormData对象,然后使用append()方法向该对象中添加字段,如下:
var formData= new FormData(); formData.append("username","Groucho"); formData.append("accountnum",123456); //fileInput中已经包含了用户所选择的文件 formData.append("userfile",fileInputElement.files[0]); var oFileBody = "<a id='a'><b id='b'>hey!</b></a>"; //Blob对象包含的文件内容 var oBlob = new Blob([oFileBody],{type:"text/xml"}); formData.append("webmasterfile",oBlob); var oReq = new XMLHttpRequest(); oReq.open("POST", "submitform.php"); oReq.send(formData);
2、使用HTML表单来初始化一个FormData对象
可以用一个已有的<form>元素来初始化FormData对象,只需要把这份form元素作为参数传入FormData构造函数即可。
var newFormData = new FormData(someFormElement);
例如:
var formElement = document.getElementById("myFormElement"); var oReq = new XMLHttpRequest(); oReq.open("POST", "submitform.php"); oReq.send(new FormData(formElement));
还可以在已有表单数据的基础上,继续添加新的键值对,如:
var formElement = document.getElementById("myFormElement"); formData = new FormData(formElement); formData.append("serialnumber", serialNumber++); oReq.send(formData);
可以通过这种方法添加一些不想让用户编辑的固定字段,然后再发送。
3、使用FormData对象发送文件
可以使用FormData来发送二进制文件,首先在HTML中要有包含文件输入框的form元素:
<form enctype="multipart/form-data" method="post" name="fileinfo"> <label>Your email address:</label> <input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br /> <label>Custom file label:</label> <input type="text" name="filelabel" size="12" maxlength="32" /><br /> <label>File to stash:</label> <input type="file" name="file" required /> </form> <div id="output"></div> <a href="javascript:sendForm()">Stash the file!</a>
然后你就可以使用下面的代码来异步的上传用户所选择的文件:
function sendForm() { var oOutput = document.getElementById("output"); var oData = new FormData(document.forms.namedItem("fileinfo")); oData.append("CustomField", "This is some extra data"); var oReq = new XMLHttpRequest(); oReq.open("POST", "stash.php", true); oReq.onload = function(oEvent) { if (oReq.status == 200) { oOutput.innerHTML = "Uploaded!"; } else { oOutput.innerHTML = "Error " + oReq.status + " occurred uploading your file.<br \/>"; } }; oReq.send(oData);}
你还可以不借助HTML表单,直接向FormData
对象中添加一个File
对象或者一个Blob
对象:
data.append("myfile", myBlob);
如果FormData对象中的某个字段值是一个Blob
对象,则在发送http请求时,代表该Blob
对象所包含文件的文件名的"Content-Disposition"请求头的值在不同的浏览器下有所不同,Firefox使用了固定的字符串"blob,"而Chrome使用了一个随机字符串。
你还可以使用jQuery来发送FormData,但必须要正确的设置相关选项
:
var fd = new FormData(document.getElementById("fileinfo")); fd.append("CustomField", "This is some extra data");$.ajax({ url: "stash.php", type: "POST", data: fd, processData: false, // 告诉jQuery不要去处理发送的数据 contentType: false // 告诉jQuery不要去设置Content-Type请求头});