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中sort()方法的用法
Nov 04 Javascript
为JavaScript类型增加方法的实现代码(增加功能)
Dec 29 Javascript
多个datatable共存造成多个表格的checkbox都被选中
Jul 11 Javascript
jquery中加载图片自适应大小主要实现代码
Aug 23 Javascript
javascript匿名函数应用示例介绍
Mar 07 Javascript
如何用jQuery实现ASP.NET GridView折叠伸展效果
Sep 26 Javascript
Bootstrap每天必学之轮播(Carousel)插件
Apr 25 Javascript
js简单实现调整网页字体大小的方法
Jul 23 Javascript
微信公众号-获取用户信息(网页授权获取)实现步骤
Oct 21 Javascript
微信提示 在浏览器打开 效果实现过程解析
Sep 10 Javascript
详解Typescript 内置的模块导入兼容方式
May 31 Javascript
Element Notification通知的实现示例
Jul 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地址引用(php地址引用的效率问题)
2012/03/23 PHP
Laravel 4 初级教程之视图、命名空间、路由
2014/10/30 PHP
Codeigniter框架实现获取分页数据和总条数的方法
2014/12/05 PHP
php+Memcached实现简单留言板功能示例
2017/02/15 PHP
js资料prototype 属性
2007/03/13 Javascript
javascript中substr,substring,slice.splice的区别说明
2010/11/25 Javascript
JS打印gridview实现原理及代码
2013/02/05 Javascript
使用js判断TextBox控件值改变然后出发事件
2014/03/07 Javascript
javascript深拷贝(deepClone)详解
2016/08/24 Javascript
js中字符型和数值型数字的互相转化方法(必看)
2017/04/25 Javascript
vue-router实现webApp切换页面动画效果代码
2017/05/25 Javascript
vue2.0 自定义日期时间过滤器
2017/06/07 Javascript
Bootstrap模态框插入视频的实现代码
2017/06/25 Javascript
Vue2.0结合webuploader实现文件分片上传功能
2018/03/09 Javascript
Vue SPA 初次进入加载动画实现代码
2019/11/14 Javascript
python中aioysql(异步操作MySQL)的方法
2019/04/11 Python
python实现微信防撤回神器
2019/04/29 Python
详解python程序中的多任务
2020/09/16 Python
Python数据可视化常用4大绘图库原理详解
2020/10/23 Python
使用phonegap查找联系人的实现方法
2017/03/31 HTML / CSS
舒适的豪华鞋:Taryn Rose
2018/05/03 全球购物
网站域名和主机:Domain.com
2019/04/01 全球购物
SAZAC的动物连体衣和动物睡衣:Kigurumi Shop
2020/03/14 全球购物
新加坡最早生产电动滑板车的制造商之一:FunsToTheFore
2020/09/08 全球购物
介绍一下SQL注入攻击的种类和防范手段
2012/02/18 面试题
养殖人员的创业计划书范文
2013/12/26 职场文书
综合实践活动方案
2014/02/14 职场文书
会计学毕业生求职信
2014/06/25 职场文书
实现中国梦思想汇报2014
2014/09/13 职场文书
绍兴鲁迅故居导游词
2015/02/09 职场文书
摩登时代观后感
2015/06/03 职场文书
新闻发布会新闻稿
2015/07/17 职场文书
爱心捐赠活动简讯
2015/07/20 职场文书
婚礼伴郎致辞
2015/07/28 职场文书
安全生产学习心得体会
2016/01/18 职场文书
JS前端轻量fabric.js系列之画布初始化
2022/08/05 Javascript