前端开发中,每当遇到要写文件上传的功能的时候,第一时间就是去百度搜搜看有没有什么好用的插件。通常要么是用iframe
,要么是用一些基于jQuery
的插件。(实际也是利用iframe
)
现在有了HTML5
的FormData
技术,无需插件就可以实现文件上传功能了,方便多了。本篇博文记录一下我使用FormData
上传图片的功能实现。
FormData简介
XMLHttpRequest Level 2
添加了一个新的接口FormData
.利用FormData
对象,我们可以通过JavaScript
用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest
的send()
方法来异步的提交这个”表单”.比起普通的ajax
,使用FormData
的最大优点就是我们可以异步上传一个二进制文件. —- 来自mozilla MDN
XMLHttpRequest
就是我们使用的ajax
技术,简单来说FormData
提供了一种直接异步上传文件的技术。
利用FormData
对象,你可以使用一系列的键值对来模拟一个完整的表单,然后使用XMLHttpRequest
发送这个”表单”。
“Talk is Cheap”,让我们直接来看使用实例吧。
实例
1. 首先来看一下MDN提供的用例
1.1 创建FormData对象
1 | var oMyForm = new FormData(); |
上例构造了一个oMyForm
的dataForm
对象,包含了"username","accountnum","userfile"
以及"webmasterfile"
的字段,然后用ajax将他们提交。
还可以使用表单来初始化一个FormData对象
1.2 使用HTML表单来初始化对象
只需要把这个form元素作为参数传入FormData的构造函数即可。1
2
3
4var formElement = document.getElementById("myForm");
var oReq = new XMLHttpRequest();
oReq.open("POST","submitform.php");
oReq.send(new FormData(formElement));
总体来说跟上述是一样的,只是上例是自己构造,该处是用form表单来构造对象。
2.使用FormData上传文件
接下来看一下我的使用实例,上传图片。
首先,要有一个包含了文件输入框的form元素。
HTML容器部分如下:1
2
3
4
5
6
7
8
9
10<div class="col-md-5">
<span>身份证正面照片</span>
<form method="post" action="javascript:;" id="idCardFace" enctype="multipart/form-data">
<input type="file" class="form-control" name="pidCard" accept="image/gif,image/jpeg,image/png"/>
<input type="submit" name="submit" value="点击上传" class="btn btn-default btn-primary">
</form>
<div class="preview">
<img src="" alt="idCardFaceImg">
</div>
</div>
这里需要注意,form
表单的enctype
属性需要设置为multipart/form-data
才能提交二进制数据。
主要就是关注这一点,以及一个type=file
的input
控件,别的代码可以忽略。
JS部分:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15var formEle = $(btn).parent()[0];
var formData = new FormData(fileEle);
formData.append("userInfo",global.userInfo);
$.ajax({
url: "xxxx",
type: "POST",
data: formData,
cache: false,
contentType: false, //告诉jquery不要设置content-type头部
processData: false //告诉jquery不要对参数进行处理
}).done(function(ret) {
//上传成功处理流程
}).fail(function() {
//上传失败处理流程
});
简单分析一下,首先根据FormData的使用方式,我们需要将HTML中的form
传递给构造函数,因此首先要获取到form元素。btn
是上述HTML
容器中的”点击上传”按钮,我们需要使用$(btn).parent()[0]
来获取到form
元素。
然后,在传递之前,我还利用append
函数为对象插入了一个额外的字段,类似于普通表单传递时利用type=hidden
的input
来传递一些额外信息。
构造完毕之后就是调用ajax将对象发送出去了。
3.结果示意图
试了下,现今的几大主流浏览器Chrome,firefox,IE11,Safari
都支持了,可以放心大胆的使用了。