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将相对路径转绝对路径示例
Mar 14 Javascript
iframe的onreadystatechange事件在firefox下的使用
Apr 16 Javascript
js精美的幻灯片画集特效代码分享
Aug 29 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
Oct 21 Javascript
JavaScript实现自动切换图片代码
Oct 11 Javascript
简单的vue-resourse获取json并应用到模板示例
Feb 10 Javascript
JS实现经典的中国地区三级联动下拉菜单功能实例【测试可用】
Jun 06 Javascript
Angular 2父子组件数据传递之@Input和@Output详解(下)
Jul 05 Javascript
9102年webpack4搭建vue项目的方法步骤
Feb 20 Javascript
JavaScript创建、读取和删除cookie
Sep 03 Javascript
js实现消灭星星(web简易版)
Mar 24 Javascript
js简单实现自动生成表格功能示例
Jun 02 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
ionCube 一款类似zend的PHP加密/解密工具
2010/07/25 PHP
mysqli_set_charset和SET NAMES使用抉择及优劣分析
2013/01/13 PHP
解析PHP实现多进程并行执行脚本
2013/06/18 PHP
Ajax+PHP快速上手及简单应用说明
2013/07/24 PHP
微信公众平台网页授权获取用户基本信息中授权回调域名设置的变动
2014/10/21 PHP
Zend Framework教程之动作的基类Zend_Controller_Action详解
2016/03/07 PHP
一段实时更新的时间代码
2006/07/07 Javascript
juqery 学习之四 筛选过滤
2010/11/30 Javascript
jquery移动节点实例
2015/01/14 Javascript
nodejs中使用多线程编程的方法实例
2015/03/24 NodeJs
全面解析Javascript无限添加QQ好友原理
2016/06/15 Javascript
AngularJS下对数组的对比分析
2016/08/24 Javascript
15分钟深入了解JS继承分类、原理与用法
2019/01/19 Javascript
vue+elementui实现点击table中的单元格触发事件--弹框
2020/07/18 Javascript
浅谈Vue使用Cascader级联选择器数据回显中的坑
2020/10/31 Javascript
[02:07]2018DOTA2亚洲邀请赛主赛事第三日五佳镜头 fy极限反杀
2018/04/06 DOTA
[01:03]PWL开团时刻DAY6——别打我
2020/11/05 DOTA
Python给你的头像加上圣诞帽
2018/01/04 Python
python简单商城购物车实例代码
2018/03/15 Python
Django自定义过滤器定义与用法示例
2018/03/22 Python
python字典值排序并取出前n个key值的方法
2018/10/17 Python
python中ImageTk.PhotoImage()不显示图片却不报错问题解决
2018/12/06 Python
解决django后台样式丢失,css资源加载失败的问题
2019/06/11 Python
python将字符串list写入excel和txt的实例
2019/07/20 Python
django实现支付宝支付实例讲解
2019/10/17 Python
python函数装饰器之带参数的函数和带参数的装饰器用法示例
2019/11/06 Python
python实现FTP文件传输的方法(服务器端和客户端)
2020/03/20 Python
Django 拼接两个queryset 或是两个不可以相加的对象实例
2020/03/28 Python
利用Python实现Json序列化库的方法步骤
2020/09/09 Python
社团文化节策划书
2014/02/01 职场文书
总经理任命书范本
2014/06/05 职场文书
2014年无财产无子女离婚协议书范本
2014/10/09 职场文书
可可西里观后感
2015/06/08 职场文书
python 破解加密zip文件的密码
2021/04/22 Python
MySQL数字类型自增的坑
2021/05/07 MySQL
python 常用的异步框架汇总整理
2021/06/18 Python