jQuery+formdata實現上傳進度特效遇到的問題
總結我做HTML5文件上傳插件遇到的技術問題
先貼上源碼:fileupload-html5.js(PS:公司使用seajs框架)
問題列表
1. JQUERY.AJAX沒有監(jiān)聽上傳進度的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事件可以監(jiān)聽上傳進度。既然jQ沒有給出這個功能的api,但jQ某些數據上傳方式是使用XHR的,所以我們可以從其它api中找到XHR。在XHR發(fā)送數據之前綁定onprogress事件可以實現上傳進度功能。
我從OPTIONS參數配置中找到兩個與XHR有關的屬性:
- XHR:回調創(chuàng)建XMLHTTPREQUEST對象。
xhr()返回值是XHR,提供給jQ使用,即發(fā)送數據就是用這個XHR。我們可以通過xhr創(chuàng)建一個回調函數覆蓋它,同樣返回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內部創(chuàng)建的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)支持跨域,但需要后臺允許。
//后臺需發(fā)送頭部驗證
if($_REQUEST['cros']) {
header("Access-Control-Allow-Origin:請求的域名");
}
根據后臺給的接口,我需要增加一個參數cros。但我將這個參數與文件同事提交,卻提示跨域限制。最后將這個參數放在url才行。
原來XHR跨域是有兩次請求的,第一次是驗證請求,瀏覽器根據請求目的地址自動發(fā)出options請求。若通過,才能發(fā)出自定義的post請求。所以將參數放在post請求里,第一次請求沒有cros參數,即不能通過。
相關文章
jQuery 順便學習下CSS選擇器 奇偶匹配nth-child(even)
今天學習jQuery,看到nth-child(even)用法,特意找了下這個選擇器的用法,在CSS3標準中,用法很強大。2010-05-05
jQuery EasyUI API 中文文檔 - MenuButton菜單按鈕使用介紹
jQuery EasyUI API 中文文檔 - MenuButton菜單按鈕使用介紹,使用jQuery EasyUI的朋友可以參考下。2011-10-10

