H5 FormData对象的使用——进行Ajax请求并上传文件
XMLHttpRequest Level2 添加了一个新的接口——FormData 。【 主要用于发送表单数据,但也可以独立使用于传输键控数据。与普通的Ajax相比,它能异步上传二进制文件 】
利用FormData对象,可通过js用一些键值对来模拟一系列表单控件,还可以使用XMLHttpRequest的send()方法异步提交表单。
首先,在之前的“前后台交互之传参方式”中讲了传统的form表单提交的方式(表单序列化),它只适用于传递一般参数,上传文件的文件流是无法被序列化并传递的。所以,使用FormData,可以轻松的和ajax结合进行文件上传。
一、在介绍使用FormData进行Ajax请求并上传文件之前,先来认识一下FormData以及它的使用:::::
W3C 草案提供了三种方案来获取或修改 Form Data :::
WAY1:创建一个空的 Form Data 对象,再用 append() 逐个添加键值对
var oMyForm = new FormData(); // 创建一个空的FormData对象 oMyForm.append("userName","Coco"); // append()方法添加字段 oMyForm.append("accountNum",123456); // 数字123456立即被转换成字符串“123456” oMyForm.append("userFile",fileInputElement.files[0]); var oFileBody = "<a id="a"><b id="b">hey!</b></a>"; var oBlob = new Blob([oFileBody],{type:"text/html"}); // Blob对象包含的文件内容是oFileBody oMyForm.append("webmasterfile",oBlob); var oReq = new XMLHttpRequest(); oReq.open("POST"," .php"); oPeq.send(oMyForm); // 使用XMLHttpRequest的send()把数据发送出去
上面的"userFile"和"webmasterfile"的值都包含了一个文件;
字段的值可以是一个Blob对象,File对象或者字符串,别的类型都会被自动转换成字符串——例如上面的"accountNum" 。
WAY2:取form元素对象作为参数传入FormData对象中
—— 伪代码 ——
var new_FormData = new FormData( someFormElement );
例:
var FormElement = document.getElementById("myFormElement"); var oReq = new XMLHttpRequest(); oReq.open("POST"," .php"); oReq.send(new FormData(FormData));
也可以在已有表单基础上继续添加新的键值对:
var FormElement = document.getElementById("myFormElement"); var formData = new FormData(FormElement); formData.append("serialnumber",serialNumber++); var oReq = new XMLHttpRequest(); oReq.send(formData);
可以通过这种方式添加一些不想让用户编辑的固定字段,然后再发送。
WAY3:利用form对象的getFormData方法生成
var formobj = document.getElementById("myFormElement"); var formdata = formobj.getFormData();
利用 FormData 对象,结合原生的 js,通过 ajax 实现异步上传图片。当然,现在已有的 jquery 批量上传的插件,原理就是利用 FormData。
二、使用 FormData对象发送二进制文件::::::
way1:通过 form 表单来初始化 FormData
1、在 html 中有一个包含文件输入框的 form 元素
<form enctype="multipare/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>
2、异步上传用户所选的文件
function sendForm(){ var oOutput = document.getElementById("Output"); var oData = new FormData(document.forms.nameItem("fileInfo")); oData.append("customField","This is some extra data"); var oReq = new XMLHttpRequest(); oReq.open("POST"," .php",true); oReq.onload = function(oEvent){ if(oReq.status == 200){ oOutput.innerHTML = "Uploaded!"; }else{ oOutput.innerHTML = "Error" + oReq.status + "occurred uploading your file!" } }; oReq.send(oData); }
WAY2:不借助 form 表单,直接向 FormData 对象中添加一个 File 对象或者一个 Blob 对象
var data = new FormData(); var oFileBody = "<a id="a"><b id="b">hey!</b></a>"; var oBlob = new Blob([oFileBody],{type:"text/html"}); data.append("myfile",oBlob);
如果 FormData 对象中某个字段值是一个 Blob 对象,在发送 HTTP 请求时,代表该 Blob 对象所包含文件的文件名的 “content-Disposition” 请求的值在不同浏览器中不同:
Firefox 使用固定的字符串 "blob",而 chrome使用一个随机字符串。
WAY3:使用 Jquery 发送 FormData(要正确设置相关项)
var fd =new FormData(document.getElementById("fileinfo")); fd.append("customField","This is some extra data"); $.ajax({ url:" .php", type:"POST", data:fd, processData:false, // 告诉jquery不要处理发送的数据 contentType:false // 告诉jquery不要设置content-Type请求头 });
三、例子
1、使用 FromData 进行 Ajax 请求,并上传文件
<form id="uploadForm"> 指定文件名:<input type="text" name="filename" value=""> 上传文件:<input type="file" name="file"> <input type="button" value="上传" onclick="doUpload()"> </form>
function doUpload(){ var formData = new FormData($("#uploadForm")[0]); $.ajax({ url:" .php", type:"POST", data:formData, async:false, cache:false, contentType:false, processData:false, success:function(returndata){ alert(returndata); }, error:function(returndata){ alert("error:"+returndata); } }); }
2、使用 FormData 提交表单及上传图片
<form name="form" id="formData"> name:<input type="text" name="name"> gender:<input type="radio" name="gender" value="1"> male <input type="radio" name="gender" value="2"> female photo:<input type="file" name="photo" id="photo"> <input type="button" name="btn" value="submit" onclick="submit();"> </form> <div id="result"></div>
function submit(){ var data = new FormData($("#formData")[0]); $.ajax({ url:" .php", type:"POST", data:data, dataType:"JSON", cache:false, processData:false, contentType:false }).done(function(ret){ if(ret["isSuccess"]){ var result = ""; result +="name=" + ret["name"] + "<br>"; result += "gender=" + ret["gender"] + "<br>"; result += "<img src='"+ret['photo']+"'width='100'>"; $("#result").html(result); // 提交成功后将表单数据显示在id="result"的div里面 }else{ alert("提交失败"); } }); return false; }
四、浏览器兼容性
Chrome | Firefox(Gecko) | IE | Opera | Safari |
7+ | 4.0(2.0)+ | 10+ | 12+ | 5+ |