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接口实现代码 (Interfaces In JavaScript)
Jun 11 Javascript
JQuery优缺点分析说明
Apr 10 Javascript
JavaScript对象学习经验整理
Oct 12 Javascript
javascript从右边截取指定字符串的三种实现方法
Nov 29 Javascript
使用ajaxfileupload.js实现ajax上传文件php版
Jun 26 Javascript
JavaScript实现的encode64加密算法实例分析
Apr 15 Javascript
js H5 canvas投篮小游戏
Aug 18 Javascript
JavaScript中Array的实用操作技巧分享
Sep 11 Javascript
通过AngularJS实现图片上传及缩略图展示示例
Jan 03 Javascript
JS获取短信验证码倒计时的实现代码
May 22 Javascript
JavaScript实现三级联动菜单效果
Aug 16 Javascript
vue中v-model动态生成的实例详解
Oct 27 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 jsonp单引号转义
2014/11/23 PHP
ThinkPHP模版引擎之变量输出详解
2014/12/05 PHP
在WordPress中使用wp_count_posts函数来统计文章数量
2016/01/05 PHP
Yii2单元测试用法示例
2016/11/12 PHP
jquery的ajax从纯真网(cz88.net)获取IP地址对应地区名
2009/12/02 Javascript
Tab页界面 用jQuery及Ajax技术实现(php后台)
2011/10/12 Javascript
用表格输出1-1000之间的数字实现代码(附特效)
2013/04/21 Javascript
js使下拉列表框可编辑不止是选择
2013/12/12 Javascript
js中的for如何实现foreach中的遍历
2014/05/31 Javascript
利用js实现禁止复制文本信息
2015/06/03 Javascript
纯js实现无限空间大小的本地存储
2015/06/18 Javascript
JavaScript简单下拉菜单实例代码
2015/09/07 Javascript
客户端(vue框架)与服务器(koa框架)通信及服务器跨域配置详解
2017/08/26 Javascript
ES6解构赋值实例详解
2017/10/31 Javascript
vue地区选择组件教程详解
2018/05/04 Javascript
Vue移动端实现图片上传及超过1M压缩上传
2019/12/23 Javascript
在vue-cli3中使用axios获取本地json操作
2020/07/30 Javascript
Python映射拆分操作符用法实例
2015/05/19 Python
玩转python爬虫之cookie使用方法
2016/02/17 Python
python 网络爬虫初级实现代码
2016/02/27 Python
CentOS6.5设置Django开发环境
2016/10/13 Python
Python 查看文件的读写权限方法
2018/01/23 Python
PyQt4实现下拉菜单可供选择并打印出来
2018/04/20 Python
python对html过滤处理的方法
2018/10/21 Python
Python图像处理之图片文字识别功能(OCR)
2019/07/30 Python
使用python实现哈希表、字典、集合操作
2019/12/22 Python
css3弹性盒模型(Flexbox)详细介绍
2014/10/08 HTML / CSS
水果花束:Fruit Bouquets
2017/12/20 全球购物
SQL Server数据库笔试题和答案
2016/02/04 面试题
护理自荐信
2013/10/22 职场文书
简历中个人求职的自我评价模板
2013/11/29 职场文书
工程造价专业大学生职业生涯规划书
2014/01/18 职场文书
2014年青年教师工作总结
2014/12/17 职场文书
乱世佳人观后感
2015/06/08 职场文书
Python实现随机生成迷宫并自动寻路
2021/06/13 Python
PHP RabbitMQ消息列队
2022/05/11 PHP