jQuery+formdata實(shí)現(xiàn)上傳進(jìn)度特效遇到的問(wèn)題
總結(jié)我做HTML5文件上傳插件遇到的技術(shù)問(wèn)題
先貼上源碼:fileupload-html5.js(PS:公司使用seajs框架)
問(wèn)題列表
1. JQUERY.AJAX沒(méi)有監(jiān)聽(tīng)上傳進(jìn)度的ONPROGRESS事件。
2. XMLHTTPREQUEST(XHR)跨域
問(wèn)題解答
1. JQUERY沒(méi)有給出ONPROGRESS事件的接口,必須從其他接口中找到原生XHR對(duì)象。
jQuery.ajax()返回的是jqXHR對(duì)象。jqXHR模仿XHR(原生),但沒(méi)有模仿實(shí)現(xiàn)XHR的所有方法和屬性(如:.upload),即使jqXHR增加了一個(gè)特有方法(如:.promise())。所以jqXHR并不是XHR的超集。
//下面是截取jQ內(nèi)部的源碼,$.ajax();返回的就是這個(gè)jqXHR(偽造XMLHttpRequest)
// Fake xhr
jqXHR = {
readyState: 0,
XHR的upload屬性指向XMLHttpRequestUpload(IE10是XMLHttpRequestEventTarget),該對(duì)象的onprogress事件可以監(jiān)聽(tīng)上傳進(jìn)度。既然jQ沒(méi)有給出這個(gè)功能的api,但jQ某些數(shù)據(jù)上傳方式是使用XHR的,所以我們可以從其它api中找到XHR。在XHR發(fā)送數(shù)據(jù)之前綁定onprogress事件可以實(shí)現(xiàn)上傳進(jìn)度功能。
我從OPTIONS參數(shù)配置中找到兩個(gè)與XHR有關(guān)的屬性:
- XHR:回調(diào)創(chuàng)建XMLHTTPREQUEST對(duì)象。
xhr()返回值是XHR,提供給jQ使用,即發(fā)送數(shù)據(jù)就是用這個(gè)XHR。我們可以通過(guò)xhr創(chuàng)建一個(gè)回調(diào)函數(shù)覆蓋它,同樣返回XHR,但在此綁定onprogress事件。
//jQ源碼
// Get a new xhr
var handle, i,
xhr = s.xhr();//[回調(diào)]在這里,下面是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 );
}
所以我們應(yīng)該這樣做:
$.ajax({
//.....
xhr: function() {
var xhr = $.ajaxSettings.xhr();
//綁定上傳進(jìn)度的回調(diào)函數(shù)
xhr.upload.addEventListener('progress', progress, false);
return xhr;//一定要返回,不然jQ沒(méi)有XHR對(duì)象用了
}
});
- XHRFIELDS:一對(duì)“文件名-文件值”組成的映射,用于設(shè)定原生的 XHR對(duì)象。
xhrFields屬性指向jQ內(nèi)部創(chuàng)建的XHR,我們可以根據(jù)xhrFields獲得XMLHttpRequest。由于xhrFields的值只能是json對(duì)象,所以不能以下面方式獲取。
//錯(cuò)誤例子
$.ajax({
//......
xhrFields: {
upload.onprogress: function() {
//語(yǔ)法錯(cuò)誤
}
}
});
我們可以借助XHR的onsendstart事件,如下:
$.ajax({
//......
xhrFields: {
onsendstart: function() {
//this是指向XHR
this.upload.addEventListener('progress', progress, false);
}
}
});
2. XMLHTTPREQUESTⅡ(XHR)支持跨域,但需要后臺(tái)允許。
//后臺(tái)需發(fā)送頭部驗(yàn)證
if($_REQUEST['cros']) {
header("Access-Control-Allow-Origin:請(qǐng)求的域名");
}
根據(jù)后臺(tái)給的接口,我需要增加一個(gè)參數(shù)cros。但我將這個(gè)參數(shù)與文件同事提交,卻提示跨域限制。最后將這個(gè)參數(shù)放在url才行。
原來(lái)XHR跨域是有兩次請(qǐng)求的,第一次是驗(yàn)證請(qǐng)求,瀏覽器根據(jù)請(qǐng)求目的地址自動(dòng)發(fā)出options請(qǐng)求。若通過(guò),才能發(fā)出自定義的post請(qǐng)求。所以將參數(shù)放在post請(qǐng)求里,第一次請(qǐng)求沒(méi)有cros參數(shù),即不能通過(guò)。
相關(guān)文章
jQuery實(shí)現(xiàn)數(shù)字自動(dòng)增加或者減少的動(dòng)畫(huà)效果示例
這篇文章主要介紹了jQuery實(shí)現(xiàn)數(shù)字自動(dòng)增加或者減少的動(dòng)畫(huà)效果,涉及jQuery結(jié)合時(shí)間函數(shù)動(dòng)態(tài)設(shè)置元素屬性相關(guān)操作技巧,需要的朋友可以參考下2018-12-12
基于jQuery Tipso插件實(shí)現(xiàn)消息提示框特效
這篇文章主要介紹了基于jQuery Tipso插件實(shí)現(xiàn)消息提示框特效,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-03-03
jQuery實(shí)現(xiàn)的感應(yīng)鼠標(biāo)懸停圖片色彩漸顯效果
這篇文章主要介紹了jQuery實(shí)現(xiàn)的感應(yīng)鼠標(biāo)懸停圖片色彩漸顯效果,涉及jQuery中hover、find、css等方法的使用技巧,需要的朋友可以參考下2015-03-03
jquery 提示信息顯示后自動(dòng)消失的具體實(shí)現(xiàn)
讓提示信息顯示后自動(dòng)消失的方法有很多,在本文為大家介紹下使用jquery是如何做到的,感興趣朋友可以參考下2013-12-12
jQuery 順便學(xué)習(xí)下CSS選擇器 奇偶匹配nth-child(even)
今天學(xué)習(xí)jQuery,看到nth-child(even)用法,特意找了下這個(gè)選擇器的用法,在CSS3標(biāo)準(zhǔn)中,用法很強(qiáng)大。2010-05-05
jquery仿百度百科底部浮動(dòng)導(dǎo)航特效
這篇文章主要介紹了jquery仿百度百科底部浮動(dòng)導(dǎo)航特效,需要的朋友可以參考下2015-08-08
jQuery EasyUI API 中文文檔 - MenuButton菜單按鈕使用介紹
jQuery EasyUI API 中文文檔 - MenuButton菜單按鈕使用介紹,使用jQuery EasyUI的朋友可以參考下。2011-10-10
查看源碼的工具 學(xué)習(xí)jQuery源碼不錯(cuò)的工具
jQuery是一個(gè)非常好用的javascript框架,我尤其喜歡它強(qiáng)大的選擇器和鏈?zhǔn)奖磉_(dá)式,使得我們能通過(guò)簡(jiǎn)單的語(yǔ)句實(shí)現(xiàn)復(fù)雜的功能。它還有一個(gè)重要的特點(diǎn)就是它的可擴(kuò)展性,使得很多人都可以開(kāi)發(fā)他們的插件并且分享出來(lái)2011-12-12
Jquery根據(jù)瀏覽器窗口改變調(diào)整大小的方法
下面小編就為大家?guī)?lái)一篇Jquery根據(jù)瀏覽器窗口改變調(diào)整大小的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02
jquery中l(wèi)oad方法的用法及注意事項(xiàng)說(shuō)明
本篇文章主要是對(duì)jquery中l(wèi)oad方法的用法及注意事項(xiàng)進(jìn)行了詳細(xì)介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2014-02-02

