2012-03-02 28 views
7

我正在用jQuery製作簡單的autosuggestion(autocompleter)插件。不幸的是我必須使用jsonp。它是好的,它的工作原理,但是當我中止請求會拋出錯誤。正在中止jQuery JSONP請求會拋出錯誤

Uncaught TypeError: Property 'jQuery171036404498340561986_1330693563756' of object [object Window] is not a function 

有代碼

if(xhr) {xhr.abort()}; 
xhr = $.ajax({ 
    url: "someurl/getmedata", 
    type: 'get', 
    dataType: 'jsonp', 
    data: {q: "query"}, 
    success: function(results) {}, 
    error: function() {} 
}) 

與JSON,XML或其它請求,經典的方式正常工作。

安妮的建議?

+0

這個問題以前的[與jQuery中止JSONP AJAX請求(的副本http://stackoverflow.com/questions/6472509/abort-jsonp-ajax-請求與jQuery),但這個問題從來沒有得到妥善解答,而這個問題是。 – 2012-04-03 18:56:09

回答

14

JSONP使用XMLHTTPRequest但實際上創建文檔內的<script>標籤,以便能夠使跨域請求。

你根本無法中止JSONP請求。

這是$.ajax()文檔中所述:

某些類型的Ajax請求,如JSONP和跨域GET請求,不使用XHR;在這些情況下,傳遞給回調函數的XMLHttpRequest和textStatus參數是未定義的。

至於jQuery 1.5+,以前是從$ .ajax()返回XHR對象,現在它返回封裝XHR對象的超集jqXHR對象。

當輸送機構是其他東西比XMLHttpRequest的(例如,對於一個JSONP請求的腳本代碼)的jqXHR對象模擬天然XHR功能儘可能

因此,它返回一個對象,但一些函數實際上不可用,如.abort()。


插件jQuery-JSONP似乎提供了手動終止JSONP請求的可能性。我沒有使用它自己,但值得一試。

+0

好吧。有沒有其他的方式來處理全局環境中的缺失函數? – Schovi 2012-03-02 19:35:02

+1

我已經添加了一個鏈接到插件[jquery-jsonp](http://code.google.com/p/jquery-jsonp/),它似乎提供了中止jsonp請求的可能性。 – 2012-03-02 20:35:45

+0

謝謝。我會嘗試! – Schovi 2012-03-04 08:51:04

4

jQuery使用<script>標記來實現JSONP。您不能中止加載腳本標記。

0

首先,使用一些排序邏輯。這將確保您的上一次請求勝過舊的請求。 這裏您有example

另外,還可以利用這些$.ajax設置:

timeout:設置每個請求的時間限制和防止請求失敗默默。

beforeSend:在撥打電話前驗證一些條件。補碼排序助手。

As of jQuery 1.5, the beforeSend option will be called regardless of the type of request. 

實施例:

function updateResults() { 

    // Init counter & record current request 
    if (!window.reqSeq) window.reqSeq = 0; 
    window.reqSeq +=1; 
    var thisRequest = window.reqSeq; 

    $.ajax({ 
    url: [..], 
    crossDomain: true, 
    contentType: "application/json", 
    dataType: 'jsonp', 
    timeout: 5000, // give 5 seconds of margin 
    data: { [..] }, 
    beforeSend: function() { 
     if(thisRequest < window.reqSeq) { 
     return false; 
     } 
    }, 
    success: function(data, textStatus, jqXHR) { 
     if(thisRequest < window.reqSeq) { 
     return; 
     } 
     else print(data); 
    }, 
    error: function(jqXHR, textStatus, errorThrown) { 
     // it'll be called on timeout (error) and beforeSend (abort) 
     print(textStatus); 
    } 
    }); 

}