425 Stimmen

Kann jemand erklären, was JSONP in einfachen Worten ist?

Ich weiß, dass JSONP JSON mit Padding ist.

Ich verstehe, was JSON ist und wie man es mit jQuery.getJSON() verwendet. Ich verstehe jedoch nicht das Konzept des callback, wenn JSONP eingeführt wird.

Kann mir jemand erklären, wie das funktioniert?

12 Stimmen

780voto

Matt Punkte 72534

Vorwort:

Diese Antwort ist über sechs Jahre alt. Während sich die Konzepte und Anwendung von JSONP nicht geändert haben (d.h. die Details der Antwort sind immer noch gültig), sollten Sie versuchen CORS zu verwenden, wo möglich (d.h. Ihr Server oder API unterstützt es, und die Browserunterstützung ausreichend ist), da JSONP inhärente Sicherheitsrisiken hat.


JSONP (JSON mit Padding) ist eine Methode, die häufig verwendet wird, um die Cross-Domain-Richtlinien in Webbrowsern zu umgehen. (Es ist nicht erlaubt, AJAX-Anfragen an eine Webseite zu stellen, die vom Browser als auf einem anderen Server befindlich wahrgenommen wird.)

JSON und JSONP verhalten sich auf dem Client und Server unterschiedlich. JSONP-Anfragen werden nicht mithilfe von XMLHTTPRequest und den zugehörigen Browsermethoden gesendet. Stattdessen wird ein </code>-Tag erstellt, dessen Quelle auf die Zielseite gesetzt ist. Dieses Skript-Tag wird dann dem DOM hinzugefügt (normalerweise innerhalb des <code><head></code>-Elements).</p> <h3>JSON-Anfrage:</h3> <pre><code>var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { // Erfolg }; }; xhr.open("GET", "irgendwo.php", true); xhr.send(); </code></pre> <h3>JSONP-Anfrage:</h3> <pre><code>var tag = document.createElement("script"); tag.src = 'irgendwo_anders.php?callback=foo'; document.getElementsByTagName("head")[0].appendChild(tag); </code></pre> <hr> <p>Der Unterschied zwischen einer JSON-Antwort und einer JSONP-Antwort besteht darin, dass das JSONP-Antwortobjekt als Argument an eine Rückruffunktion übergeben wird.</p> <h3>JSON:</h3> <pre><code>{ "bar": "baz" } </code></pre> <h3>JSONP:</h3> <pre><code>foo( { "bar": "baz" } ); </code></pre> <hr> <p>Deshalb enthalten JSONP-Anfragen den <code>callback</code>-Parameter, damit der Server den Namen der Funktion kennt, um die Antwort einzufassen.</p> <p>Diese Funktion <em>muss</em> im globalen Bereich existieren <em>zum Zeitpunkt,</em> zu dem das <code><script></code>-Tag vom Browser ausgewertet wird (nach Abschluss der Anfrage).</p> <hr> <p>Ein weiterer Unterschied bei der Verarbeitung einer JSON-Antwort und einer JSONP-Antwort ist, dass etwaige Parsefehler in einer JSON-Antwort durch das Umschließen des Versuchs, den responseText zu evaluieren, in einem try/catch-Statement eingefangen werden können. Aufgrund der Art einer JSONP-Antwort führen Parsefehler in der Antwort zu einem nicht erfassbaren JavaScript-Parsingfehler.</p> <p>Beide Formate können Timeout-Fehler implementieren, indem ein Timeout vor dem Initiieren der Anfrage festgelegt und der Timeout im Antwort-Handler gelöscht wird. </p> <hr> <h2>Verwendung von jQuery</h2> <p>Der Vorteil der Verwendung von <a href="https://api.jquery.com/jquery.ajax/" rel="noreferrer">jQuery</a> für JSONP-Anfragen besteht darin, dass jQuery <strong><em>alle Arbeit</em></strong> im Hintergrund für Sie erledigt.</p> <p>Standardmäßig erfordert jQuery, dass Sie <code>&callback=?</code> in die URL Ihrer AJAX-Anfrage aufnehmen. jQuery wird die von Ihnen angegebene <code>success</code>-Funktion einem eindeutigen Namen zuweisen und sie im globalen Bereich veröffentlichen. Dann wird das Fragezeichen <code>?</code> in <code>&callback=?</code> durch den von jQuery zugewiesenen Namen ersetzt.</p> <hr> <h3>Vergleichbare JSON/JSONP-Implementierungen</h3> <p>Das Folgende setzt ein Antwortobjekt voraus <code>{ "bar" : "baz" }</code></p> <h3>JSON:</h3> <pre><code>var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { document.getElementById("output").innerHTML = eval('(' + this.responseText + ')').bar; }; }; xhr.open("GET", "irgendwo.php", true); xhr.send(); </code></pre> <h3>JSONP:</h3> <pre><code>function foo(response) { document.getElementById("output").innerHTML = response.bar; }; var tag = document.createElement("script"); tag.src = 'irgendwo_anders.php?callback=foo'; document.getElementsByTagName("head")[0].appendChild(tag); </code></pre></x-turndown>

74voto

sje397 Punkte 40297

Sagen wir, Sie haben eine URL, die Ihnen JSON-Daten liefert wie:

{'field': 'value'}

...und Sie haben eine ähnliche URL, außer dass sie JSONP verwendet. Dazu übergeben Sie den Callback-Funktionsnamen 'myCallback' (normalerweise durch Angabe eines Query-Parameters namens 'callback', z.B. http://example.com/dataQuelle?callback=myCallback). Dann würde es zurückgeben:

myCallback({'field':'value'})

...das ist nicht nur ein Objekt, sondern tatsächlich ausführbarer Code. Wenn Sie also woanders in Ihrer Seite eine Funktion namens myFunction definieren und dieses Skript ausführen, wird sie mit den Daten von der URL aufgerufen.

Das Tolle daran ist: Sie können ein Skript-Tag erstellen und Ihre URL (inklusive callback-Parameter) als src-Attribut verwenden, und der Browser wird es ausführen. Das bedeutet, Sie können die Same-Origin-Sicherheitsrichtlinie umgehen (weil Browser es erlauben, Skript-Tags von Quellen außerhalb der Domain der Seite auszuführen).

Das ist das, was jQuery macht, wenn Sie eine Ajax-Anfrage stellen (mit .ajax und 'jsonp' als Wert für die dataType-Eigenschaft). Z.B.

$.ajax({
  url: 'http://example.com/datasource',
  dataType: 'jsonp',
  success: function(data) {
    // Ihr Code zur Verarbeitung der Daten hier
  }
});

Hier kümmert sich jQuery um den Callback-Funktionsnamen und den Query-Parameter, so dass die API identisch zu anderen Ajax-Aufrufen ist. Aber im Gegensatz zu anderen Arten von Ajax-Anfragen sind Sie, wie bereits erwähnt, nicht darauf beschränkt, Daten aus der gleichen Ursprung wie Ihre Seite zu erhalten.

18voto

Adam Zerner Punkte 14785

JSONP ist eine Möglichkeit, um das selbe Herkunfts-Policy des Browsers zu umgehen. Wie? So:

Bildbeschreibung hier eingeben

Das Ziel hier ist, eine Anfrage an otherdomain.com zu machen und den Namen in der Antwort mit alert anzuzeigen. Normalerweise würden wir eine AJAX-Anfrage machen:

$.get('otherdomain.com', function (response) {
  var name = response.name;
  alert(name);
});

Aber da die Anfrage an eine andere Domain geht, funktioniert es nicht.

Wir können die Anfrage aber mit einem </code>-Tag machen. Sowohl <code><script src="otherdomain.com"> als auch $.get('otherdomain.com') werden die gleiche Anfrage machen:

GET otherdomain.com

Frage: Aber wenn wir das </code>-Tag verwenden, wie könnten wir auf die Antwort <em>zugreifen</em>? Wir müssen darauf zugreifen, wenn wir sie <code>alert</code> wollen.</p> <p>Antwort: Äh, das können wir nicht. Aber hier ist, was wir tun könnten - eine Funktion definieren, die die Antwort nutzt, und dann dem Server sagen, mit JavaScript zu antworten, das unsere Funktion mit der Antwort als Argument aufruft.</p> <p>Frage: Aber was ist, wenn der Server das nicht für uns machen will und nur dazu bereit ist, uns JSON zurückzugeben?</p> <p>Antwort: Dann können wir es nicht benutzen. JSONP erfordert die Zusammenarbeit des Servers.</p> <p>Frage: Ein <code><script></code>-Tag zu benutzen ist hässlich.</p> <p>Antwort: Bibliotheken wie jQuery machen es <a href="https://learn.jquery.com/ajax/working-with-jsonp/" rel="noreferrer">schöner</a>. Beispiel:</p> <pre><code>$.ajax({ url: "http://otherdomain.com", jsonp: "callback", dataType: "jsonp", success: function( response ) { console.log( response ); } }); </code></pre> <p>Es funktioniert, indem es das <code><script></code>-Tag DOM-Element dynamisch erstellt.</p> <p>Frage: <code><script></code>-Tags machen nur GET-Anfragen - was ist, wenn wir eine POST-Anfrage machen wollen?</p> <p>Antwort: Dann funktioniert JSONP nicht für uns.</p> <p>Frage: Das ist okay, ich möchte nur eine GET-Anfrage machen. JSONP ist toll und ich werde es benutzen - danke!</p> <p>Antwort: Eigentlich ist es nicht so toll. Es ist wirklich nur ein Hack. Und es <a href="https://stackoverflow.com/questions/613962/is-jsonp-safe-to-use">ist nicht das sicherste</a> zu benutzen. Jetzt, wo CORS verfügbar ist, sollten Sie es so oft wie möglich verwenden.</p></x-turndown>

3voto

Harshit Garg Punkte 1899

Ich habe einen nützlichen Artikel gefunden, der das Thema auch klar und einfach erklärt. Der Link lautet JSONP

Einige der zu beachtenden Punkte sind:

  1. JSONP wurde vor CORS eingeführt.
  2. Es ist eine halboffizielle Methode, um Daten von einer anderen Domain abzurufen,
  3. Es verfügt über eingeschränkte CORS-Funktionen (nur GET-Methode)

Die Funktionsweise ist wie folgt:

  1. </code> wird im HTML-Code eingefügt</li> <li>Wenn Schritt 1 ausgeführt wird, wird eine Funktion mit demselben Funktionsnamen (wie im URL-Parameter angegeben) als Antwort gesendet. </li> <li>Wenn die Funktion mit dem angegebenen Namen im Code existiert, wird sie mit den Daten, falls vorhanden, als Argument für diese Funktion ausgeführt. </li> </ol></x-turndown>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X