jQuery+formdata实现上传进度特效遇到的问题


Posted in Javascript onFebruary 24, 2016

总结我做HTML5文件上传插件遇到的技术问题

先贴上源码:fileupload-html5.js(PS:公司使用seajs框架)

问题列表

1. JQUERY.AJAX没有监听上传进度的ONPROGRESS事件。

2. XMLHTTPREQUEST(XHR)跨域

问题解答

1. JQUERY没有给出ONPROGRESS事件的接口,必须从其他接口中找到原生XHR对象。

jQuery.ajax()返回的是jqXHR对象。jqXHR模仿XHR(原生),但没有模仿实现XHR的所有方法和属性(如:.upload),即使jqXHR增加了一个特有方法(如:.promise())。所以jqXHR并不是XHR的超集。

//下面是截取jQ内部的源码,$.ajax();返回的就是这个jqXHR(伪造XMLHttpRequest)
// Fake xhr
 jqXHR = {

  readyState: 0,

XHR的upload属性指向XMLHttpRequestUpload(IE10是XMLHttpRequestEventTarget),该对象的onprogress事件可以监听上传进度。既然jQ没有给出这个功能的api,但jQ某些数据上传方式是使用XHR的,所以我们可以从其它api中找到XHR。在XHR发送数据之前绑定onprogress事件可以实现上传进度功能。

我从OPTIONS参数配置中找到两个与XHR有关的属性:

- XHR:回调创建XMLHTTPREQUEST对象。

xhr()返回值是XHR,提供给jQ使用,即发送数据就是用这个XHR。我们可以通过xhr创建一个回调函数覆盖它,同样返回XHR,但在此绑定onprogress事件。

//jQ源码
// Get a new xhr
var handle, i,
 xhr = s.xhr();//[回调]在这里,下面是open方法

// Open the socket
// Passing null username, generates a login popup on Opera (#2865)
if ( s.username ) {
 xhr.open( s.type, s.url, s.async, s.username, s.password );
} else {
 xhr.open( s.type, s.url, s.async );
}

所以我们应该这样做:

$.ajax({
 //.....
 xhr: function() {
  var xhr = $.ajaxSettings.xhr();
  //绑定上传进度的回调函数
  xhr.upload.addEventListener('progress', progress, false);
  return xhr;//一定要返回,不然jQ没有XHR对象用了
 }
});

- XHRFIELDS:一对“文件名-文件值”组成的映射,用于设定原生的 XHR对象。

xhrFields属性指向jQ内部创建的XHR,我们可以根据xhrFields获得XMLHttpRequest。由于xhrFields的值只能是json对象,所以不能以下面方式获取。

//错误例子
$.ajax({
 //......
 xhrFields: {
  upload.onprogress: function() {
   //语法错误
  }
 }
});

我们可以借助XHR的onsendstart事件,如下:

$.ajax({
 //......
 xhrFields: {
  onsendstart: function() {
   //this是指向XHR
   this.upload.addEventListener('progress', progress, false);
  }
 }
});

2. XMLHTTPREQUESTⅡ(XHR)支持跨域,但需要后台允许。

//后台需发送头部验证
if($_REQUEST['cros']) {
 header("Access-Control-Allow-Origin:请求的域名");
}

根据后台给的接口,我需要增加一个参数cros。但我将这个参数与文件同事提交,却提示跨域限制。最后将这个参数放在url才行。

原来XHR跨域是有两次请求的,第一次是验证请求,浏览器根据请求目的地址自动发出options请求。若通过,才能发出自定义的post请求。所以将参数放在post请求里,第一次请求没有cros参数,即不能通过。

Javascript 相关文章推荐
js两行代码按指定格式输出日期时间
Oct 21 Javascript
javascript定时器完整实例
Feb 10 Javascript
JS实现常见的TAB、弹出层效果(TAB标签,斑马线,遮罩层等)
Oct 08 Javascript
jquery移动端TAB触屏切换实现效果
Dec 22 Javascript
浅谈几种常用的JS类定义方法
Jun 08 Javascript
prototype.js简单实现ajax功能示例
Oct 18 Javascript
CSS3 动画卡顿性能优化的完美解决方案
Sep 20 Javascript
vue项目打包部署_nginx代理访问方法详解
Sep 20 Javascript
微信小程序scroll-view横向滑动嵌套for循环的示例代码
Sep 20 Javascript
微信小程序分包加载代码实现方法详解
Sep 23 Javascript
Vue extend的基本用法(实例详解)
Dec 09 Javascript
2019年度web前端面试题总结(主要为Vue面试题)
Jan 12 Javascript
JQuery EasyUI的使用
Feb 24 #Javascript
使用jQuery监听DOM元素大小变化
Feb 24 #Javascript
JavaScript中的闭包
Feb 24 #Javascript
jQuery中判断对象是否存在的方法汇总
Feb 24 #Javascript
jquery中键盘事件小结
Feb 24 #Javascript
javascript实现九宫格相加数值相等
May 28 #Javascript
Javascript类型转换的规则实例解析
Feb 23 #Javascript
You might like
php中的三元运算符使用说明
2011/07/03 PHP
解析strtr函数的效率问题
2013/06/26 PHP
PHP对表单提交特殊字符的过滤和处理方法汇总
2014/02/18 PHP
php自定义apk安装包实例
2014/10/20 PHP
php设计模式之适配器模式原理、用法及注意事项详解
2019/09/24 PHP
firefox下对ajax的onreadystatechange的支持情况分析
2009/12/14 Javascript
JavaScript arguments 多参传值函数
2010/10/24 Javascript
浅析Node.js中使用依赖注入的相关问题及解决方法
2015/06/24 Javascript
js实现文字选中分享功能
2017/01/25 Javascript
Vue组件的使用及个人理解与介绍
2019/02/09 Javascript
jQuery中使用validate插件校验表单功能
2019/05/24 jQuery
了解重排与重绘
2019/05/29 Javascript
在Vue项目中使用Typescript的实现
2019/12/19 Javascript
详解 javascript对象创建模式
2020/10/30 Javascript
JS addEventListener()和attachEvent()方法实现注册事件
2021/01/11 Javascript
[54:25]Ti4 循环赛第三日LGD vs MOUZ
2014/07/12 DOTA
Python内置函数之filter map reduce介绍
2014/11/30 Python
Django中传递参数到URLconf的视图函数中的方法
2015/07/18 Python
python Pandas 读取txt表格的实例
2018/04/29 Python
异步任务队列Celery在Django中的使用方法
2018/06/07 Python
美国汽车零部件和配件网站:CarParts
2019/03/13 全球购物
美国亚洲时尚和美容产品的一站式网上商店:Stylevana
2019/09/05 全球购物
西班牙在线宠物食品和配件商店:bitiba
2019/10/11 全球购物
美国饼干礼物和美食甜点购买网站:Cheryl’s
2020/05/28 全球购物
请说出几个常用的异常类
2013/01/08 面试题
大学毕业生通用求职信
2013/09/28 职场文书
汽车维修与检测专业应届生求职信
2013/11/12 职场文书
结婚典礼证婚词
2014/01/11 职场文书
运动会通讯稿150字
2014/02/15 职场文书
《特殊的葬礼》教学反思
2014/04/27 职场文书
学校工作推荐信范文
2014/07/11 职场文书
超市开业庆典活动策划方案
2014/09/15 职场文书
2015年安全月活动总结
2015/03/26 职场文书
停电调休通知
2015/04/16 职场文书
致短跑运动员加油稿
2015/07/21 职场文书
python编程学习使用管道Pipe编写优化代码
2021/11/20 Python