簡體   English   中英

jQuery中的並行JSONP請求不會觸發多個“回調事件”?

[英]Parallel JSONP requests in jQuery do not trigger multiple “callback events”?

當我執行多個jsonp請求時,我在jQuery中遇到問題,所有這些請求都具有相同的jsonpCallback函數。 似乎只針對其中一個回調函數被觸發。 JSONP請求是否以某種方式相互覆蓋?

下面是對github執行2個jsonp請求的示例,即使兩個firebug都顯示它們都返回,但回調函數getName僅針對其中一個調用:

function getName(response){
    alert(response.data.name);
}

function userinfo(username){
    $.ajax({
        url: "https://api.github.com/users/" + username,
        jsonpCallback: 'getName',
        dataType: "jsonp"
    });        
}

users = ["torvalds", "twitter", "jquery"]
for(var i = 0; i < users.length; i++){
  userinfo(users[i]);
}

由於jsonp的工作方式,您的請求只被觸發一次。

Jsonp意味着從外部域向頁面添加腳本標記,以繞過現代瀏覽器中構建的跨站點腳本保護(現在是2011年4月的IE6和7)。 為了讓該腳本與頁面上的其余腳本進行交互,加載的腳本需要調用頁面上的函數。 該函數必須存在於全局命名空間中,這意味着該名稱只能有一個函數。 換句話說,沒有JQuery,單個jsonp請求將如下所示:

<script>
function loadJson(json) {
    // Read the json
}
</script>
<script src="//outsidedomain.com/something.js"></script>

其中something.js看起來像這樣:

loadJson({name:'Joe'})

在這種情況下,something.js有一個硬編碼的回調來加載它攜帶的JSON,頁面有一個硬編碼的loadJson函數,等待像這樣的腳本加載和調用它。

現在假設您希望能夠從多個源加載json並告訴每個源何時完成,或者甚至多次從同一源加載JSON,並且能夠告知每個調用何時完成 - 即使一個調用延遲了很長時間它完成之后的電話。 這種硬編碼方法不再適用,原因有兩個:

  1. 每次加載something.js都會調用相同的loadJson()回調 - 你無法知道哪個請求與哪個回復有關。

  2. 緩存 - 一旦你加載something.js一次,瀏覽器就不會再向服務器詢問它 - 它只是將它從緩存中恢復,破壞了你的計划。

您可以通過告訴服務器每次都以不同方式包裝JSON來解決這兩個問題,並且簡單的方法是在查詢字符串參數中傳遞該信息,例如?callback=loadJson12345 好像你的頁面看起來像這樣:

<script>
function loadJson1(json) {
    // Read the json
}
function loadJson2(json) {
    // Read the json
}
</script>
<script src="//outsidedomain.com/something.js?callback=loadJson1"></script>
<script src="//outsidedomain.com/somethingelse.js?callback=loadJson2"></script>

使用JQuery,這些都是抽象的,看起來像是對.ajax的正常調用,這意味着你期望觸發成功函數。 為了確保為每個jsonp加載觸發正確的成功函數,JQuery在全局命名空間中創建一個長的隨機回調函數名稱,如JQuery1233432432432432,將其作為查詢字符串中的回調參數傳遞,然后等待加載腳本。 如果一切正常,加載的腳本將調用JQuery請求的回調函數,而后者又從$ .ajax調用中觸發成功處理程序。

請注意,“正常工作”要求服務器端讀取?callback querystring參數並將其包含在響應中,例如?callback=joe - > joe({...如果它是靜態文件或服務器不以這種方式玩,你可能需要將文件視為可緩存 - 見下文。

高速緩存

如果你想讓你的json緩存,你可以通過設置cache:true並將jsonpCallback屬性設置為硬編碼到可緩存的json文件中的字符串,讓JQuery更接近我的第一個例子。 例如這個靜態json:

loadJoe({name:'Joe'})

可以像這樣在JQuery中加載和緩存:

$.ajax({
    url: '//outsidedomain.com/loadjoe.js',
    dataType: 'jsonp',
    cache: true,
    jsonpCallback: 'loadJoe',
    success: function(json) { ... }
});

使用成功回調代替..

function userinfo(username){
    $.ajax({
        url: "https://api.github.com/users/" + username,
        success: getName,
        dataType: "jsonp"
    });        
}
$(function() {
    function userinfo(username){
      var XHR = $.ajax({
             url: "https://api.github.com/users/" + username,
             dataType: "jsonp"
         }).done(function(data) {
             console.log(data.data.name);
         });
    }

    users = ["torvalds", "twitter", "jquery"];
    for(var i = 0; i < users.length; i++){
       userinfo(users[i]);
    }
});  ​

不確定,但我從github API調用得到的響應不包括gravatar_id

這對我有用:

function getGravatar(response){
    var link = response.data.avatar_url;
    $('#list').append('<div><img src="' + link + '"></div>');
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM