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 当前日期加(天、周、月、年)
Aug 09 Javascript
jQuery中大家不太了解的几个方法
Mar 04 Javascript
JS中的eval 为什么加括号
Apr 13 Javascript
CKEditor无法验证的解决方案(js验证+jQuery Validate验证)
May 09 Javascript
JavaScript生成验证码并实现验证功能
Sep 24 Javascript
使用微信内嵌H5网页解决JS倒计时失效问题
Jan 13 Javascript
javascript获取以及设置光标位置
Feb 16 Javascript
基于vue实现分页/翻页组件paginator示例
Mar 09 Javascript
JavaScript变量作用域_动力节点Java学院整理
Jun 27 Javascript
详解vuex的简单使用
Mar 12 Javascript
JS原型prototype和__proto__用法实例分析
Mar 14 Javascript
js+css实现扇形导航效果
Aug 18 Javascript
遍历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与XML的PDF文档生成技术
2006/10/09 PHP
Discuz! 5.0.0论坛程序中加入一段js代码,让会员点击下载附件前自动弹出提示窗口
2007/04/18 PHP
php 函数使用方法与函数定义方法
2010/05/09 PHP
PHP学习散记_编码(json_encode 中文不显示)
2011/11/10 PHP
最新制作ThinkPHP3.2.3完全开发手册
2015/11/23 PHP
yii2 开发api接口时优雅的处理全局异常的方法
2019/05/14 PHP
[原创]保存的js无法执行的解决办法
2007/02/25 Javascript
Jquery选择子控件&quot;大于号&quot;和&quot; &quot;区别介绍及使用示例
2013/06/25 Javascript
javascript解决IE6下hover问题的方法
2015/07/28 Javascript
《JavaScript高级编程》学习笔记之object和array引用类型
2015/11/01 Javascript
浅谈javascript中的constructor
2016/06/08 Javascript
JavaScript检测原始值、引用值、属性
2016/06/20 Javascript
JS实现的系统调色板完整实例
2016/12/21 Javascript
值得收藏的八个常用的js正则表达式
2018/10/19 Javascript
vue-openlayers实现地图坐标弹框效果
2020/09/24 Javascript
浅谈Vue开发人员的7个最好的VSCode扩展
2021/01/20 Vue.js
Python实现计算最小编辑距离
2016/03/17 Python
pycharm创建一个python包方法图解
2019/04/10 Python
Python集中化管理平台Ansible介绍与YAML简介
2019/06/12 Python
PYTHON如何读取和写入EXCEL里面的数据
2019/10/28 Python
如何查看Django ORM执行的SQL语句的实现
2020/04/20 Python
Python实现疫情通定时自动填写功能(附代码)
2020/05/27 Python
基于css3仿造window7的开始菜单
2010/06/17 HTML / CSS
CSS3中的clip-path使用攻略
2015/08/03 HTML / CSS
Proenza Schouler官方网站:纽约女装和配饰品牌
2019/01/03 全球购物
托管代码(Managed Code)和非托管代码(Unmanaged Code)有什么区别
2014/09/29 面试题
新兵入伍心得体会
2014/09/04 职场文书
统计学教授推荐信
2014/09/18 职场文书
同学毕业留言寄语
2015/02/27 职场文书
体检通知范文
2015/04/21 职场文书
校长一岗双责责任书
2015/05/09 职场文书
不同意离婚上诉状
2015/05/23 职场文书
关于MySQL中的 like操作符详情
2021/11/17 MySQL
Python日志模块logging用法
2022/06/05 Python
django项目、vue项目部署云服务器的详细过程
2022/07/23 Servers
java获取一个文本文件的编码(格式)信息
2022/09/23 Java/Android