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 相关文章推荐
fromCharCode和charCodeAt 方法
Dec 27 Javascript
javascript模拟的Ping效果代码 (Web Ping)
Mar 13 Javascript
禁用键盘上的(全局)指定键兼容iE、Chrome、火狐
May 14 Javascript
浅析JavaScript中的隐式类型转换
Dec 05 Javascript
js跨域请求的5中解决方式
Jul 02 Javascript
ES6深入理解之“let”能替代”var“吗?
Jun 28 Javascript
JS实现身份证输入框的输入效果
Aug 21 Javascript
微信通过页面(H5)直接打开本地app的解决方法
Sep 09 Javascript
解决layui页面按钮点击无反应,也不报错的问题
Sep 29 Javascript
VUE table表格动态添加一列数据,新增的这些数据不可以编辑(v-model绑定的数据不能实时更新)
Apr 03 Javascript
jQuery-App输入框实现实时搜索
Nov 19 jQuery
面试中canvas绘制图片模糊图片问题处理
Mar 13 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屏蔽关键字实现方法
2016/11/17 PHP
PHP正则之正向预查与反向预查讲解与实例
2020/04/06 PHP
JavaScript 继承详解(一)
2009/07/13 Javascript
js 绑定键盘鼠标事件示例代码
2014/02/12 Javascript
解决用jquery load加载页面到div时,不执行页面js的问题
2014/02/22 Javascript
jQuery中document与window以及load与ready 区别详解
2014/12/29 Javascript
13个PHP函数超实用
2015/10/21 Javascript
跟我学习javascript的this关键字
2020/05/28 Javascript
Bootstrap实现水平排列的表单
2016/07/04 Javascript
js enter键激发事件实例代码
2016/08/17 Javascript
H5移动端适配 Flexible方案
2016/10/24 Javascript
原生js编写2048小游戏
2017/03/17 Javascript
ES6新数据结构Map功能与用法示例
2017/03/31 Javascript
说说AngularJS中的$parse和$eval的用法
2017/09/14 Javascript
JS实现的简单表单验证功能示例
2017/10/13 Javascript
Layui多选只有最后一个值的解决方法
2019/09/02 Javascript
JS错误处理与调试操作实例分析
2020/04/13 Javascript
python实现文件路径和url相互转换的方法
2015/07/06 Python
Python DataFrame 设置输出不显示index(索引)值的方法
2018/06/07 Python
使用numpy和PIL进行简单的图像处理方法
2018/07/02 Python
替换python字典中的key值方法
2018/07/06 Python
Python 实现域名解析为ip的方法
2019/02/14 Python
详解如何设置Python环境变量?
2019/05/13 Python
详解Python 定时框架 Apscheduler原理及安装过程
2019/06/14 Python
Django ORM 查询管理器源码解析
2019/08/05 Python
python socket通信编程实现文件上传代码实例
2019/12/14 Python
pytorch torch.nn.AdaptiveAvgPool2d()自适应平均池化函数详解
2020/01/03 Python
解决python3插入mysql时内容带有引号的问题
2020/03/02 Python
自荐信要包含哪些内容
2013/11/06 职场文书
关于奉献的演讲稿
2014/05/21 职场文书
扬尘污染防治方案
2014/06/15 职场文书
领导班子四风对照检查材料
2014/09/23 职场文书
2015年学校医务室工作总结
2015/07/20 职场文书
2015年政教主任工作总结
2015/07/23 职场文书
详解nginx安装过程并代理下载服务器文件
2022/02/12 Servers
英镑符号 £
2022/02/17 杂记