[英]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,並且能夠告知每個調用何時完成 - 即使一個調用延遲了很長時間它完成之后的電話。 這種硬編碼方法不再適用,原因有兩個:
每次加載something.js都會調用相同的loadJson()回調 - 你無法知道哪個請求與哪個回復有關。
緩存 - 一旦你加載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.