jQuery用FormData实现文件上传的方法
前言
我们引入jQuery来进行异步上传可以获得更好的用户体验。一方面,在JavaScript中进行异步操作比表单更加灵活;另一方面,异步上传也避免了上传大文件时的页面长时间卡死。
HTML
一个type=file的<input>就可以让用户来浏览并选择文件,一般会把输入控件放到一个<form>中,下面的一个简单的表单:
<form> <inputtype="file"id="avatar"name="avatar"> <buttontype="button">保存</button> </form>
但为什么我只能选择一个文件??给<input>添加一个multiple属性就可以多选了!
<inputtype="file"id="avatar"name="avatar"multiple>
获取文件列表
上述的<input>将会拥有一个叫files的DOM属性,包含了所选的文件列表(Array)。
$('button').click(function(){ var$input=$('#avatar'); //相当于:$input[0].files,$input.get(0).files varfiles=$input.prop('files'); console.log(files); });
这个Array中的每一项都是一个File对象,它有下面几个主要属性:
name:文件名,只读字符串,不包含任何路径信息.
size:文件大小,单位为字节,只读的64位整数.
type:MIME类型,只读字符串,如果类型未知,则返回空字符串.
详情可以参考:https://developer.mozilla.org/zh-CN/docs/Using_files_from_web_applications
multipart/form-data
上传文件比较特殊,其内容是二进制数据,而HTTP提供的是基于文本的通信协议。这时需要采用multipart/form-data编码的HTTP表单。
其HTTP消息体格式如下所示:
------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition:form-data;name="title" harttle ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition:form-data;name="avatar";filename="harttle.png" Content-Type:image/png ...contentofharttle.png... ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
每个字段由一段boundarystring来分隔,浏览器保证该boundarystring不与内容重复,因而multipart/form-data能够成功编码二进制数据。
jQuery上传文件
这是XMLHttpRequestLevel2提供的FormData对象可以帮助我们进行二进制文件的multipart/form-data编码:
$('button').click(function(){ varfiles=$('#avatar').prop('files'); vardata=newFormData(); data.append('avatar',files[0]); $.ajax({ url:'/api/upload', type:'POST', data:data, cache:false, processData:false, contentType:false }); });
url,type,data想必做前端的都很熟悉了,介绍其余三个参数:
cache
cache设为false可以禁止浏览器对该URL(以及对应的HTTP方法)的缓存。jQuery通过为URL添加一个冗余参数来实现。
该方法只对GET和HEAD起作用,然而IE8会缓存之前的GET结果来响应POST请求。这里设置cache:false是为了兼容IE8。
参考:http://api.jquery.com/jquery.ajax/
contentType
jQuery中content-type默认值为application/x-www-form-urlencoded,因此传给data参数的对象会默认被转换为querystring(见HTTP表单编码enctype)。
我们不需要jQuery做这个转换,否则会破坏掉multipart/form-data的编码格式。因此设置contentType:false来禁止jQuery的转换操作。
processData
jQuery会将data对象转换为字符串来发送HTTP请求,默认情况下会用application/x-www-form-urlencoded编码来进行转换。我们设置contentType:false后该转换会失败,因此设置processData:false来禁止该转换过程。
我们给的data就是已经用FormData编码好的数据,不需要jQuery进行字符串转换。
兼容性与其他选择
本文介绍的jQuery文件上传方式依赖于FormData对象,这是XMLHttpRequestLevel2接口,需要IE10+,Firefox4.0+,Chrome7+,Safari5+,Opera12+
这意味着对于低版本浏览器只能使用直接提交文件表单的形式,但提交大文件表单页面会长时间不响应,如果希望在低版本浏览器中解决该问题,就只能使用别的方式来实现了,比如很多支持多文件和上传进度的Flash插件。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。谢谢大家对毛票票的支持。