jQuery用FormData实现文件上传的方法


Posted in Javascript onNovember 21, 2016

前言

我们引入jQuery来进行异步上传可以获得更好的用户体验。 一方面,在JavaScript中进行异步操作比表单更加灵活; 另一方面,异步上传也避免了上传大文件时的页面长时间卡死。

HTML

一个type=file<input>就可以让用户来浏览并选择文件, 一般会把输入控件放到一个<form>中,下面的一个简单的表单:

<form>
 <input type="file" id="avatar" name="avatar">
 <button type="button">保存</button>
</form>

但为什么我只能选择一个文件??给<input>添加一个multiple属性就可以多选了!

<input type="file" id="avatar" name="avatar" multiple>

获取文件列表

上述的<input>将会拥有一个叫files的DOM属性,包含了所选的文件列表(Array)。

$('button').click(function(){
 var $input = $('#avatar');
 // 相当于: $input[0].files, $input.get(0).files
 var files = $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

 ... content of harttle.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

每个字段由一段boundary string来分隔,浏览器保证该boundary string不与内容重复, 因而multipart/form-data能够成功编码二进制数据。

jQuery上传文件

这是XMLHttpRequest Level 2提供的FormData对象可以帮助我们进行二进制文件的 multipart/form-data编码:

$('button').click(function(){
 var files = $('#avatar').prop('files');

 var data = new FormData();
 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参数的对象会默认被转换为query string(见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对象, 这是XMLHttpRequest Level 2接口, 需要 IE 10+, Firefox 4.0+, Chrome 7+, Safari 5+, Opera 12+

这意味着对于低版本浏览器只能使用直接提交文件表单的形式, 但提交大文件表单页面会长时间不响应,如果希望在低版本浏览器中解决该问题, 就只能使用别的方式来实现了,比如很多支持多文件和上传进度的Flash插件。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jquery ui 1.7 ui.tabs 动态添加与关闭(按钮关闭+双击关闭)
Apr 01 Javascript
如何用js控制frame的隐藏或显示的解决办法
Mar 20 Javascript
Egret引擎开发指南之编译项目
Sep 03 Javascript
javascript HTML5 Canvas实现圆盘抽奖功能
Apr 11 Javascript
js实现模糊匹配功能
Feb 15 Javascript
javascript九宫格图片随机打乱位置的实现方法
Mar 15 Javascript
原生JS实现圆环拖拽效果
Apr 07 Javascript
jQuery实现动态显示select下拉列表数据的方法
Feb 05 jQuery
AngularJS自定义表单验证功能实例详解
Aug 24 Javascript
vue实现element表格里表头信息提示功能(推荐)
Nov 20 Javascript
微信小程序实现自定义底部导航
Nov 18 Javascript
vue 页面跳转的实现方式
Jan 12 Vue.js
遍历js中对象的属性和值的实例
Nov 21 #Javascript
JavaScript数据结构链表知识详解
Nov 21 #Javascript
jQuery简单自定义图片轮播插件及用法示例
Nov 21 #Javascript
Node.js测试中的Mock文件系统详解
Nov 21 #Javascript
JavaScript中boolean类型之三种情景实例代码
Nov 21 #Javascript
基于jQuery实现Tabs选项卡自定义插件
Nov 21 #Javascript
基于jQuery实现Accordion手风琴自定义插件
Oct 13 #Javascript
You might like
php防止恶意刷新与刷票的方法
2014/11/21 PHP
PHP调用Linux命令权限不足问题解决方法
2015/02/07 PHP
PHP simplexml_load_file()函数讲解
2019/02/03 PHP
php连接mysql数据库最简单的实现方法
2019/09/24 PHP
HTML 自动伸缩的表格Table js实现
2009/04/01 Javascript
select多选 multiple的使用示例
2014/06/16 Javascript
JavaScript高级教程5.6之基本包装类型(详细)
2015/11/23 Javascript
基于jquery实现省市区三级联动效果
2015/12/25 Javascript
JS给swf传参数的实现方法
2016/09/13 Javascript
jQuery插件FusionCharts实现的MSBar2D图效果示例【附demo源码】
2017/03/24 jQuery
利用canvas实现的加载动画效果实例代码
2017/07/05 Javascript
vue jsx 使用指南及vue.js 使用jsx语法的方法
2017/11/11 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
2018/01/16 Javascript
Vue指令指令大全
2019/02/09 Javascript
react写一个select组件的实现代码
2019/04/03 Javascript
JS实现网站吸顶条
2020/01/08 Javascript
jQuery实现移动端下拉展现新的内容回弹动画
2020/06/24 jQuery
[01:03:54]Liquid vs IG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
[00:59]PWL开团时刻DAY7——我在赶
2020/11/06 DOTA
Python中str is not callable问题详解及解决办法
2017/02/10 Python
11月编程语言排行榜 Python逆袭C#上升到第4
2017/11/15 Python
Python 字符串与二进制串的相互转换示例
2018/07/23 Python
pandas把所有大于0的数设置为1的方法
2019/01/26 Python
Python如何生成xml文件
2020/06/04 Python
HTML5地理定位与第三方工具百度地图的应用
2016/11/17 HTML / CSS
印度尼西亚在线时尚购物网站:ZALORA印尼
2016/08/02 全球购物
FLIR美国官网:热成像, 夜视和红外摄像系统
2018/07/13 全球购物
意大利男装网店:Vrients
2019/05/02 全球购物
英国水族馆和池塘用品购物网站:Warehouse Aquatics
2019/08/29 全球购物
毕业生求职简历的自我评价
2013/10/07 职场文书
工作自荐信
2013/12/11 职场文书
社会实践活动总结范文
2014/07/03 职场文书
十八大宣传标语
2014/10/09 职场文书
高中班主任评语
2014/12/30 职场文书
开场白怎么写
2015/06/01 职场文书
2016全国“质量月”活动标语口号
2015/12/26 职场文书