Parallele JSONP-Anforderungen in jQuery lösen nicht mehrere "Callback-Ereignisse" aus?

7

Ich habe ein Problem in jQuery, wenn ich mehrere jsonp-Anfragen mit derselben jsonpCallback-Funktion mache. Es scheint, dass nur für die eine von denen die Callback-Funktion ausgelöst wird. Sind JSONP-Anforderungen irgendwie gegenseitig überschrieben?

Im Folgenden ein Beispiel für die Ausführung von 2 jsonp-Anfragen an github, und obwohl beide Firebugs zeigen, dass beide zurückkehren, wird die Callback-Funktion getName nur für eine von ihnen aufgerufen:

%Vor%     
Jeroen 23.04.2012, 23:06
quelle

4 Antworten

19

Ihre Anfrage wurde nur einmal ausgelöst, weil jsonp funktioniert.

Jsonp bedeutet das Hinzufügen eines Skript-Tags zu der Seite von einer externen Domäne, um die in modernen Browsern integrierten Cross-Site-Scripting-Schutzmechanismen zu umgehen (und jetzt IE6 und 7 ab April 2011). Damit dieses Skript mit dem Rest des Skripts auf der Seite interagieren kann, muss das geladene Skript eine Funktion auf der Seite aufrufen. Diese Funktion muss im globalen Namespace vorhanden sein, dh es kann nur eine Funktion mit diesem Namen geben. Mit anderen Worten, ohne JQuery würde eine einzelne jsonp-Anfrage wie folgt aussehen:

%Vor%

Wo something.js so aussehen würde:

%Vor%

something.js hat in diesem Fall einen hartcodierten Callback, um den JSON zu laden, den es trägt, und die Seite hat eine fest programmierte loadJson-Funktion, die darauf wartet, dass Skripte wie diese geladen und aufgerufen werden.

Nehmen wir nun an, Sie möchten JSON von mehreren Quellen laden und sagen, wann jeder fertig ist, oder sogar JSON mehrfach von derselben Quelle laden und in der Lage sein, zu sagen, wann jeder Anruf beendet wird - selbst wenn ein Anruf so verzögert wird lang ist es nach einem späteren Anruf beendet. Dieser hart codierte Ansatz wird aus zwei Gründen nicht mehr funktionieren:

  1. Jede Ladung von something.js ruft denselben Aufruf von loadJson () auf - Sie haben keine Möglichkeit zu wissen, welche Anfrage zu welcher Antwort gehört.

  2. Caching - Sobald Sie something.js einmal laden, wird der Browser den Server nicht erneut darum bitten - er wird es einfach aus dem Cache zurückholen und Ihren Plan ruinieren.

Sie können beide auflösen, indem Sie dem Server sagen, dass er den JSON jedes Mal anders umbrechen soll, und der einfache Weg besteht darin, diese Informationen in einem Querystring-Parameter wie ?callback=loadJson12345 zu übergeben. Es ist, als ob deine Seite so aussieht:

%Vor%

Mit JQuery wird dies alles abstrahiert, damit Sie wie ein normaler Aufruf von $ .ajax aussehen, was bedeutet, dass Sie erwarten, dass die Erfolgsfunktion ausgelöst wird. Um sicherzustellen, dass die richtige Erfolgsfunktion für jede jsonp-Last ausgelöst wird, erstellt JQuery im globalen Namespace einen langen, zufälligen Callback-Funktionsnamen wie JQuery1233432432432432, übergibt diesen als Callback-Parameter im Querystring und wartet dann auf das Laden des Skripts. Wenn alles ordnungsgemäß funktioniert, ruft das Skript, das lädt, die von JQuery angeforderte Rückruffunktion auf, die wiederum den Erfolgshandler aus dem $ .ajax-Aufruf auslöst.

Beachten Sie, dass "funktioniert ordnungsgemäß" erfordert, dass die Server-Seite den Parameter ?callback querystring liest und das in der Antwort wie ?callback=joe - & gt; %Code%. Wenn es sich um eine statische Datei handelt oder der Server nicht auf diese Weise wiedergegeben wird, müssen Sie die Datei wahrscheinlich als cachefähig behandeln - siehe unten.

Caching

Wenn Sie möchten, dass Ihr json zwischenspeichert, können Sie JQuery veranlassen, etwas näher an meinem ersten Beispiel zu tun, indem Sie cache: true setzen und die jsonpCallback -Eigenschaft auf eine Zeichenfolge setzen, die fest in die cachefähige json-Datei geschrieben ist. Zum Beispiel dieses statische json:

%Vor%

Kann wie folgt in JQuery geladen und zwischengespeichert werden:

%Vor%     
Chris Moschini 04.05.2012, 02:59
quelle
3

Verwenden Sie stattdessen den Erfolgsrückruf ..

%Vor%     
Gaby aka G. Petrioli 23.04.2012 23:12
quelle
1
%Vor%     
adeneo 23.04.2012 23:28
quelle
0

Nicht sicher, aber die Antwort, die ich von diesem Aufruf an die github-API erhalte, enthält nicht gravatar_id .

Das hat für mich funktioniert:

%Vor%     
Cheeso 23.04.2012 23:19
quelle

Tags und Links