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 相关文章推荐
JavaScript中对象property的读取和写入方法介绍
Dec 30 Javascript
jQuery晃动层特效实现方法
Mar 09 Javascript
js实现延迟加载的方法
Jun 24 Javascript
js实现头像图片切割缩放及无刷新上传图片的方法
Jul 17 Javascript
微信小程序 MINA文件结构
Oct 17 Javascript
vue组件实例解析
Jan 10 Javascript
详解jquery选择器的原理
Aug 01 jQuery
angular2 ng2-file-upload上传示例代码
Aug 23 Javascript
Element Input组件分析小结
Oct 11 Javascript
Vue开发Html5微信公众号的步骤
Apr 11 Javascript
js blob类型url的视频下载问题的解决
Nov 29 Javascript
使用typescript改造koa开发框架的实现
Feb 04 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编写的SVN类
2013/07/18 PHP
[原创]ThinkPHP让../Public在模板不解析(直接输出)的方法
2015/10/09 PHP
详解如何实现Laravel的服务容器的方法示例
2019/04/15 PHP
在修改准备发的批量美化select+可修改select时,在非IE下发现了几个问题
2007/01/09 Javascript
javascript学习网址备忘
2007/05/29 Javascript
模仿JQuery sortable效果 代码有错但值得看看
2009/11/05 Javascript
ExtJs grid行 右键菜单的两种方法
2010/06/19 Javascript
IE之动态添加DOM节点触发window.resize事件
2010/07/27 Javascript
js继承的实现代码
2010/08/05 Javascript
基于jquery的cookie的用法
2011/01/10 Javascript
JavaScript根据数据生成百分比图和柱状图的实例代码
2013/07/14 Javascript
JavaScript 和 Java 的区别浅析
2013/07/31 Javascript
jQuery和AngularJS的区别浅析
2015/01/29 Javascript
深入浅析jQuery对象$.html
2016/08/22 Javascript
vue.js实现表格合并示例代码
2016/11/30 Javascript
微信小程序 功能函数小结(手机号验证*、密码验证*、获取验证码*)
2017/12/08 Javascript
解决使用Vue.js显示数据的时,页面闪现原始代码的问题
2018/02/11 Javascript
原生js调用json方法总结
2018/02/22 Javascript
微信小程序日历效果
2018/12/29 Javascript
详解babel升级到7.X采坑总结
2019/05/12 Javascript
VUE:vuex 用户登录信息的数据写入与获取方式
2019/11/11 Javascript
python处理json数据中的中文
2014/03/06 Python
Python正则表达式教程之一:基础篇
2017/03/02 Python
python3之微信文章爬虫实例讲解
2017/07/12 Python
Python基于numpy灵活定义神经网络结构的方法
2017/08/19 Python
Python基于matplotlib实现绘制三维图形功能示例
2018/01/18 Python
Python文本统计功能之西游记用字统计操作示例
2018/05/07 Python
浅析python的优势和不足之处
2018/11/20 Python
Python 解码Base64 得到码流格式文本实例
2020/01/09 Python
浅谈python 类方法/静态方法
2020/09/18 Python
TensorFlow2.0使用keras训练模型的实现
2021/02/20 Python
简述Linux文件系统通过i节点把文件的逻辑结构和物理结构转换的工作过程
2016/01/06 面试题
库房主管岗位职责
2013/12/31 职场文书
环保倡议书500字
2014/05/15 职场文书
详解非极大值抑制算法之Python实现
2021/06/28 Python
「女孩的钓鱼慢活」全新版权绘公布
2022/03/21 日漫