今天同事在用jQuery的ajax方法去調用一個jsonp的api時,服務端出現了500錯誤,可是前端的jQuery代碼卻沒有觸發error事件,代碼以下:javascript
$.ajax({ url: 'http://ptres.37.com/js/sq/modules/base44.js', type: 'GET', dataType: 'jsonp' }) .done(function() { console.log("success"); }) .fail(function() { console.log("error"); }).always(function(){ console.log("always"); });
如上的一段代碼,在服務端出錯時(http狀態碼爲:5XX、4XX),ajax綁定的done, fail, always方法居然一個都沒有被觸發。挺意外的,爲何這樣呢?難道是jQuery的bug?前端
仔細思考下jsonp的實現原理,其實不難找出問題的緣由。java
jsonp調用時實際上是在header中建立一個script的dom節點,而後經過script的資源調用方式去向遠程服務器發送請求的,問題的關鍵就在這個script標籤上。若是想知道這個資源地址有沒有請求成功,我首先想到的是onload和onerror這兩個回調函數,遺憾的是,ie6,7,8都是不支持script的onload和onerror回調!我想,這個應該是jquery沒法捕獲到這個錯誤的緣由吧。jquery
那麼有沒有其它辦法來處理這個錯誤呢,答案是有的,而且很簡單,只要加上timeout參數便可:ajax
$.ajax({ url: 'http://ptres.37.com/js/sq/modules/base44.js', type: 'GET', timeout: 2000, dataType: 'jsonp' }) .done(function() { console.log("success"); }) .fail(function() { console.log("error"); }).always(function(){ console.log("always"); });