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 相关文章推荐
javascript 写类方式之一
Jul 05 Javascript
js通过googleAIP翻译PHP系统的语言配置的实现代码
Oct 17 Javascript
JavaScript监听和禁用浏览器回车事件实例
Jan 31 Javascript
javascript事件委托的用法及其好处简析
Apr 04 Javascript
深入理解jQuery之事件移除
Jun 02 Javascript
浅谈angular4.0中路由传递参数、获取参数最nice的写法
Mar 12 Javascript
解决angularjs前后端分离调用接口传递中文时中文乱码的问题
Aug 13 Javascript
vue项目创建并引入饿了么elementUI组件的步骤
Apr 11 Javascript
JS实现点击生成UUID的方法完整实例【基于jQuery】
Jun 12 jQuery
在layui中layer弹出层点击事件无效的解决方法
Sep 05 Javascript
openlayers4.6.5实现距离量测和面积量测
Sep 25 Javascript
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
Jan 22 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产生动态的影像图
2006/10/09 PHP
Linux下将excel数据导入到mssql数据库中的方法
2010/02/08 PHP
WordPress中is_singular()函数简介
2015/02/05 PHP
php数据库操作model类(使用__call方法)
2016/11/16 PHP
php实现自定义中奖项数和概率的抽奖函数示例
2017/05/26 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
2017/11/14 PHP
PHP二维数组实现去除重复项的方法【保留各个键值】
2017/12/21 PHP
浅谈laravel aliases别名的原理
2019/10/24 PHP
PHP生成随机密码4种方法及性能对比
2020/12/11 PHP
在JavaScript中获取请求的URL参数[正则]
2010/12/25 Javascript
解析瀑布流布局:JS+绝对定位的实现
2013/05/08 Javascript
javascript自定义右键弹出菜单实现方法
2015/05/25 Javascript
JavaScript检测字符串中是否含有html标签实现方法
2015/07/01 Javascript
jQuery弹出层后禁用底部滚动条(移动端关闭回到原位置)
2016/08/29 Javascript
详解ECMAScript typeof用法
2018/07/25 Javascript
jQuery实现表格隔行换色
2018/09/01 jQuery
基于VSCode调试网页JavaScript代码过程详解
2020/07/20 Javascript
python 获取本机ip地址的两个方法
2013/02/25 Python
Python中的os.path路径模块中的操作方法总结
2016/07/07 Python
python 实现删除文件或文件夹实例详解
2016/12/04 Python
CentOS 7下安装Python 3.5并与Python2.7兼容并存详解
2017/07/07 Python
python多线程socket编程之多客户端接入
2017/09/12 Python
使用DataFrame删除行和列的实例讲解
2018/04/08 Python
对pandas里的loc并列条件索引的实例讲解
2018/11/15 Python
python pygame实现方向键控制小球
2019/05/17 Python
简单了解python高阶函数map/reduce
2019/06/28 Python
简单了解python PEP的一些知识
2019/07/13 Python
python创建属于自己的单词词库 便于背单词
2019/07/30 Python
Python爬虫 bilibili视频弹幕提取过程详解
2019/07/31 Python
详解python中的数据类型和控制流
2019/08/08 Python
结合OpenCV与TensorFlow进行人脸识别的实现
2019/10/10 Python
使用Python内置模块与函数进行不同进制的数的转换
2020/04/26 Python
Keras Convolution1D与Convolution2D区别说明
2020/05/22 Python
CSS3使用多列制作瀑布流
2016/05/10 HTML / CSS
世界领先的豪华床上用品供应商之一:Bedeck Home
2019/03/18 全球购物
财务分析个人的自荐书范文
2013/11/24 职场文书