总结我做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
参数,即不能经由过程。