2011-06-24 118 views
16

我正在使用JSONP ajax調用從一個不同的域加載一些內容,並且如果用戶在按鈕上導致「鼠標懸停」,所有這些東西都會執行。使用jQuery中止JSONP ajax請求

我可以捕獲$ .ajax()調用返回爲xhr對象,並在用戶每次引起「鼠標懸停」時使用它來中止ajax請求。但是JSONP回調函數仍然被調用,並且這會導致錯誤,並且我認爲這是因爲xhr.abort()方法不會阻止回調函數被調用。

我嘗試過使用try {} catch(e){}調用$ .ajax()調用,但在調用xhr.abort()方法後,錯誤仍然存​​在。

有沒有辦法處理這個異常?

凸起的例外是這樣的(根據螢火蟲): jQuery16102234208755205157_1308941669256不是一個函數

和異常的內部結構是這樣的: jQuery16102234208755205157_1308941669256({...我的JSON從數據不同的域...})

+0

可能的重複[使用jquery使用javascript殺死ajax請求](http://stackoverflow.com/questions/446594/kill-ajax-requests-using-javascript-using-jquery) – Neal

+3

我想這不是重複,因爲這個問題是關於在JSONP ajax請求上調用jqxhr.abort()方法之後防止發生異常,而不是關於如何停止請求本身。 –

+0

這個問題的答案可以在重複問題http:// stackoverflow找到。com/questions/9533848/aborting-jquery-jsonp-request-will-throw-error –

回答

-2

在jQuery 1.5中,所有Ajax API都有一個圍繞本機XHR對象的包裝對象。看一看:

http://api.jquery.com/jQuery.ajax/#jqXHR

jqxhr.abort(); // should be what you're looking for 
+2

這就是我現在正在使用的答案。這會中止ajax請求。但是這個ajax請求使用JSONP。在使用「abort()」方法之後,調用jQuery內部生成的用於處理JSONP響應的javascript函數,但abort方法似乎刪除了該函數定義或其他東西,因爲有一個我沒有的異常能夠處理。 –

+0

你有更多的信息嗎?現場示例,異常消息? –

11

最基本的答案僅僅是一個給定的here:你不能真正abort()一個JSONP調用。所以真正的問題是,你如何避免多餘的回調調用和你看到的錯誤?

您不能在回調周圍使用try...catch,因爲它是異步的;你必須從jQuery的最後抓住它,而jQuery通常不處理從回調中拋出的異常。 (我在我的書Async JavaScript中對此進行了討論)。您想要做的是爲每個Ajax調用使用唯一的標識符,並且在調用成功回調時檢查該標識符是否與您撥打電話時相同。下面是一個簡單的實現:

var requestCount = 0; 
$.ajax(url, { 
    dataType: 'jsonp', 
    requestCount: ++requestCount, 
    success: function(response, code) { 
    if (requestCount !== this.requestCount) return; 
    // if we're still here, this is the latest request... 
    } 
}); 

在這裏,我採取的任何東西傳遞給$.ajax附加到的二手作爲回調this對象的事實。

當然,如果jQuery使abort()爲我們做到這一點,那會很好。

1

jsonpString覆蓋jsonp請求中的回調函數名稱。這個值將被用來代替'callback =?'中的'回調'。部分查詢字符串在URL中。因此{jsonp:'onJSONPLoad'}會導致'onJSONPLoad=?'傳遞到服務器。從jQuery 1.5開始,將jsonp選項設置爲false可防止jQuery將?callback字符串添加到URL或嘗試使用=?進行轉換。在這種情況下,您還應該明確設置jsonpCallback設置。例如,{ jsonp: false, jsonpCallback: "callbackName" }

http://api.jquery.com/jQuery.ajax/

jQuery的增加?callback=jQuery17109492628197185695_1339420031913和後來的請求數據作爲參數設置給此回調,這樣你纔會有:

jQuery17109492628197185695_1339420031913({ 
    "status": 200, 
    "data": {your json} 
}) 

爲了避免設置附加參數請求URL和呼叫回調,將此參數添加到ajax方法:jsonp:false,因此它將看起來像:

$.ajax({ 
    ... 
    jsonp:false, 
    ... 
}); 
0

Trevor Burnham的答案相當不錯,但不是跟蹤請求計數,而應該將請求與XHR參數進行比較,就像這樣;

doRequest: function() { 
    this._freeRequest(); 

    this._request = $.getJSON(url + params + '&callback=?', function(response, status, xhr) { 
     if (this._request !== xhr) return; // aborted 

     // success 
    }.bind(this)).done(this._freeRequest.bind(this)); 
} 

_freeRequest: function() { 
    if (this._request) { 
     delete this._request; 
    } 
} 

調用doRequest試或_freeRequest一旦先前請求完成之前,將導致「流產」的說,通過使if (this._request !== xhr)線要求成爲真正的,因爲this._request將被刪除或另一個請求完全。

1

不要放棄請求

只是存儲某處XHR對象

theXHR = $.ajax(.... 

如果用戶取消該請求空保存對象

// user canceled 
theXHR = null; 

最後,當你收到響應(success回調)回調wi將比較響應的XHR對象和保存的對象。

function successCallback(data, textStatus, XHR) 
{ 
    if(theXHR !== XHR) 
    { 
     // user canceled; discard the response 
     return; 
    } 

    // process the response 
} 

沒有jQuery錯誤。


作爲一般建議不要依賴abort(),甚至經常Ajax請求。

  1. 在你不想拯救bacause 您發送的請求將被處理並沒有辦法阻止它服務器上的資源的任何情況下。答案會回來。

  2. 一些(較舊的)瀏覽器不能正確處理abort()

只是 「緩存」 XHR對象和處理自己取消場景。