使用jQuery連續發起jsonp請求失敗的緣由

jQuery的 jsonp 你們應該是十分熟悉了。php

曾遇到過這樣的需求ajax

一、但願請求幾個類似的內容添加到頁面json

二、請求的內容必定時間內是固定不變的,但願作個緩存。緩存

因而腦子一拍寫下了相似這樣的代碼 複製代碼服務器

for(var i = 0; i < 3; i++){
    $.ajax({
        url:'.../return.php?num='+i,
        dataType: 'jsonp',
        jsonp: 'callback',
        jsonpCallback: 'dosome',
        cache: true
    }).done(function(re){
        console.log(re);
    }).fail(function(){
        console.log('fail');
    });
}

複製代碼函數

結果卻老是隻有一個成功並報錯jsonp

Uncaught TypeError: dosome is not a functionurl

百思不得其解,不是有一個成功了嗎?dosome怎麼就不是函數了? 無奈之下花了大心思和時間在localhost上研究了jQuery的jsonp原理。code

設置服務器返回以下回調函數

<?php 
    echo 'dosome("num='.$_GET['num'].'");';
?>

獲得返回以下

仔細翻看源碼,在1.11.3版本發現

原來每次jsonp請求,jQuery都自動先把callbackName函數註冊到window,又在返回後把window[ callbackName ]改回來。

因而同步執行完for循環發送請求後,處理第一個返回時就把window[ callbackName ]改爲了 undefined,後續的返回都沒法處理了。

我一陣鬱悶,反正這個函數也沒執行什麼,不改回去不行嗎?

惋惜,我仍是太天真,其實不改回去也同樣沒法正常獲得想要的結果的。

我的理解,jQuery的jsonp原理大體以下

每次jsonp請求,都是新建一個處理函數把返回內容賦值到局部變量responseContainer,而後在調用註冊的回調函數以對應的局部變量responseContainer[0]爲參數執行。

當使用不一樣的處理函數名時,一切相安無事(當咱們不寫jsonpCallback時,jQuery會自動生成惟一不一樣的函數名)。就如同上面的dosome1,2,3,各自引用並處理。

而使用一樣的函數名時,循環時window['dosome']順序被賦值,最終指向最後一個處理函數(如圖中紅線),其餘的都被回收了。第一個返回時執行,把內容賦值到最後一個局部變量。

這樣,第一個請求會拿不到返回內容從而fail,而最後一個請求的回調卻處理了不是本身請求的內容。

相關文章
相關標籤/搜索