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 checkbox,radio是否选中的判断代码
Mar 20 Javascript
Bootstrap每天必学之按钮
Nov 26 Javascript
JS判断当前页面是否在微信浏览器打开的方法
Dec 08 Javascript
JQuery点击行tr实现checkBox选中的简单实例
May 26 Javascript
jQuery 选择器(61种)整理总结
Sep 26 Javascript
Javascript将字符串日期格式化为yyyy-mm-dd的方法
Oct 27 Javascript
jQuery实现立体式数字滚动条增加效果
Dec 21 Javascript
详解webpack分包及异步加载套路
Jun 29 Javascript
基于Vue、Vuex、Vue-router实现的购物商城(原生切换动画)效果
Jan 09 Javascript
详解vue-video-player使用心得(兼容m3u8)
Aug 23 Javascript
vue使用lodop打印控件实现浏览器兼容打印的方法
Feb 07 Vue.js
Vue 打包后相对路径的引用问题
Jun 05 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通用检测函数集合
2011/02/08 PHP
php字符串操作常见问题小结
2016/10/11 PHP
PHP实现关键字搜索后描红功能示例
2019/07/03 PHP
PHP命名空间用法实例分析
2019/09/04 PHP
php面向对象重点知识分享
2019/09/27 PHP
THINKPHP5分页数据对象处理过程解析
2020/10/28 PHP
从Ajax到JQuery Ajax学习
2007/02/14 Javascript
JavaScript 类的定义和引用 JavaScript高级培训 自定义对象
2010/04/27 Javascript
js 关于=+与+=日期函数使用说明(赋值运算符)
2011/11/15 Javascript
jscript读写二进制文件的方法
2015/04/22 Javascript
如何清除IE10+ input X 文本框的叉叉和密码输入框的眼睛图标
2016/12/21 Javascript
javascript容错处理代码(屏蔽js错误)
2017/01/20 Javascript
Vue-resource实现ajax请求和跨域请求示例
2017/02/23 Javascript
Angularjs中数据绑定的实例详解
2017/08/25 Javascript
详解nodejs http请求相关总结
2019/03/31 NodeJs
node实现简单的增删改查接口实例代码
2019/08/22 Javascript
[01:00]DOTA2 store: Collection of Artisan's Wonders
2015/08/12 DOTA
[40:53]完美世界DOTA2联赛PWL S3 Magma vs DLG 第二场 12.18
2020/12/20 DOTA
使用Python3制作TCP端口扫描器
2017/04/17 Python
详解使用python3.7配置开发钉钉群自定义机器人(2020年新版攻略)
2020/04/01 Python
浅谈keras保存模型中的save()和save_weights()区别
2020/05/21 Python
使用Python实现音频双通道分离
2020/12/25 Python
利用python为PostgreSQL的表自动添加分区
2021/01/18 Python
Python图像处理之膨胀与腐蚀的操作
2021/02/07 Python
css3实现针线缝合效果(图解步骤)
2013/02/04 HTML / CSS
移动端Web页面的CSS3 flex布局快速上手指南
2016/05/31 HTML / CSS
英国顶级家庭折扣店:The Works
2017/09/06 全球购物
美国最流行的男士时尚网站:Touch of Modern
2018/02/05 全球购物
日本索尼音乐商店:Sony Music Shop
2018/07/17 全球购物
销售员岗位职责范本
2014/02/03 职场文书
企业指导教师评语
2014/04/28 职场文书
淘宝好评语大全
2014/05/05 职场文书
办公室岗位职责
2015/02/04 职场文书
《烈火英雄》观后感:致敬和平时代的英雄
2019/11/11 职场文书
MySQL中连接查询和子查询的问题
2021/09/04 MySQL
MySQL count(*)统计总数问题汇总
2022/09/23 MySQL