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 preload&lazy load
May 13 Javascript
jQuery JSON的解析方式分享
Apr 05 Javascript
动态改变div的z-index属性的简单实例
Aug 08 Javascript
使用 JavaScript 进行函数式编程 (一) 翻译
Oct 02 Javascript
js Canvas实现的日历时钟案例分享
Dec 25 Javascript
webpack2.0搭建前端项目的教程详解
Apr 05 Javascript
Node.js搭建小程序后台服务
Jan 03 Javascript
vue的全局提示框组件实例代码
Feb 26 Javascript
element-ui多文件上传的实现示例
Apr 10 Javascript
微信小程序 导入图标实现过程详解
Oct 11 Javascript
vue使用@scroll监听滚动事件时,@scroll无效问题的解决方法详解
Oct 15 Javascript
基于vue与element实现创建试卷相关功能(实例代码)
Dec 07 Vue.js
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 mail 通过Windows的SMTP发送邮件失败的解决方案
2009/05/27 PHP
PHP中实现汉字转区位码应用源码实例解析
2010/06/14 PHP
《PHP编程最快明白》第三讲:php数组
2010/11/01 PHP
php中取得文件的后缀名?
2012/02/20 PHP
php生成略缩图代码
2012/07/16 PHP
解析zend studio中直接导入svn中的项目的方法步骤
2013/06/21 PHP
简单实用的PHP防注入类实例
2014/12/05 PHP
百度地图经纬度转换到腾讯地图/Google 对应的经纬度
2015/08/28 PHP
jQuery源码分析之Event事件分析
2010/06/07 Javascript
jquery聚焦文本框与扩展文本框聚焦方法
2012/10/12 Javascript
jquery实现通用版鼠标经过淡入淡出效果
2014/06/15 Javascript
将HTML格式的String转化为HTMLElement的实现方法
2014/08/07 Javascript
javascript中获取class的简单实现
2016/07/12 Javascript
jQuery绑定事件的四种方式介绍
2016/10/31 Javascript
Bootstrap CSS布局之表格
2016/12/17 Javascript
基于JavaScript实现类名的添加与移除
2017/04/23 Javascript
微信小程序图片横向左右滑动案例
2017/05/19 Javascript
Vue.js 2.5新特性介绍(推荐)
2017/10/24 Javascript
mpvue微信小程序多列选择器用法之省份城市选择的实现
2019/03/07 Javascript
vue 实现setInterval 创建和销毁实例
2020/07/21 Javascript
elementui更改el-dialog关闭按钮的图标d的示例代码
2020/08/04 Javascript
Python中使用dom模块生成XML文件示例
2015/04/05 Python
linux环境下Django的安装配置详解
2019/07/22 Python
python logging 日志的级别调整方式
2020/02/21 Python
移动端Web页面的CSS3 flex布局快速上手指南
2016/05/31 HTML / CSS
使用CSS3的box-sizing属性解决div宽高被内边距撑开的问题
2016/06/28 HTML / CSS
HTML5 canvas基本绘图之填充样式实现
2016/06/27 HTML / CSS
美国宠物用品网站:Value Pet Supplies
2018/03/17 全球购物
自我鉴定模板
2013/10/29 职场文书
财务会计专业推荐信
2013/11/30 职场文书
2015年党员自我剖析材料
2014/12/17 职场文书
优秀员工推荐材料
2014/12/20 职场文书
七一建党节慰问信
2015/02/14 职场文书
2019年作为一名实习生的述职报告
2019/09/29 职场文书
Mysql查询时间区间日期列表,不会由于数据表数据影响
2022/04/19 MySQL