TL; DR
JSONP ist ein alter Trick, der erfunden wurde, um die Sicherheitsbeschränkung zu umgehen, die es uns verbietet, JSON-Daten von einem anderen Server (einem anderen Ursprung * ) abzurufen.
Der Trick funktioniert mit einem <script>
Tag, das an dieser Stelle nach dem JSON fragt, z. B.: { "user":"Smith" }
Aber in eine Funktion eingeschlossen, das eigentliche JSONP ("JSON with Padding"):
peopleDataJSONP({"user":"Smith"})
Wenn wir es in dieser Form erhalten, können wir die Daten innerhalb unserer peopleDataJSONP
Funktion verwenden. JSONP ist eine schlechte Praxis , verwenden Sie es nicht (siehe unten)
Das Problem
Angenommen, wir navigieren weiter ourweb.com
und möchten JSON-Daten (oder wirklich alle Rohdaten) abrufen anotherweb.com
. Wenn wir eine GET-Anfrage verwenden würden (z. B. XMLHttpRequest
einen fetch
Anruf $.ajax
usw.), würde unser Browser uns mitteilen, dass dieser hässliche Fehler nicht zulässig ist:
Wie bekomme ich die gewünschten Daten? Nun, <script>
Tags unterliegen nicht dieser gesamten Serverbeschränkung (Ursprung *)! Aus diesem Grund können wir eine Bibliothek wie jQuery oder Google Maps fehlerfrei von jedem Server wie einem CDN laden.
Wichtiger Punkt : Wenn Sie darüber nachdenken, handelt es sich bei diesen Bibliotheken um tatsächlichen, ausführbaren JS-Code (normalerweise eine umfangreiche Funktion mit der gesamten Logik). Aber Rohdaten? JSON-Daten sind kein Code . Es gibt nichts zu rennen; Es sind nur einfache Daten.
Daher gibt es keine Möglichkeit, mit unseren wertvollen Daten umzugehen oder sie zu manipulieren. Der Browser lädt die Daten herunter, auf die unser <script>
Tag zeigt, und beschwert sich bei der Verarbeitung zu Recht:
WTF ist dieser {"user":"Smith"}
Mist, den wir geladen haben? Es ist kein Code. Ich kann nicht berechnen, Syntaxfehler!
Der JSONP-Hack
Der alte / hackige Weg, diese Daten zu nutzen? Wir brauchen diesen Server, um ihn mit einer gewissen Logik zu senden. Wenn er geladen ist, kann Ihr Code im Browser diese Daten verwenden. Der fremde Server sendet uns also die JSON-Daten innerhalb einer JS-Funktion. Die Daten selbst werden als Eingabe dieser Funktion eingerichtet. Es sieht aus wie das:
peopleDataJSONP({"user":"Smith"})
Das macht es zu JS-Code, den unser Browser analysiert, ohne sich zu beschweren! Genau wie bei der jQuery-Bibliothek. Um dies zu erreichen, "fragt" der Client den JSONP-freundlichen Server danach, normalerweise wie folgt:
<script src="https://anotherweb.com/api/data-from-people.json?myCallback=peopleDataJSONP"></script>
Unser Browser empfängt das JSONP mit diesem Funktionsnamen, daher benötigen wir eine Funktion mit demselben Namen in unserem Code wie folgt:
const peopleDataJSONP = function(data){
alert(data.user); // "Smith"
}
Oder so, das gleiche Ergebnis:
function peopleDataJSONP(data){
alert(data.user); // "Smith"
}
Der Browser lädt das JSONP herunter und führt es aus, wodurch unsere Funktion aufgerufen data
wird , wobei das Argument unser JSON ist. Wir können jetzt mit unseren Daten machen, was wir wollen.
Verwenden Sie nicht JSONP, sondern CORS
JSONP ist ein Cross-Site-Hack mit einigen Nachteilen:
- Wir können nur GET-Anfragen ausführen
- Da es sich um eine GET-Anforderung handelt, die durch ein einfaches Skript-Tag ausgelöst wird, erhalten wir keine hilfreichen Fehler oder Fortschrittsinformationen
- Es gibt auch einige Sicherheitsbedenken, z. B. das Ausführen in Ihrem Client-JS-Code, der in eine schädliche Nutzlast geändert werden kann
- Es löst nur das Problem mit JSON-Daten, aber die Sicherheitsrichtlinie von Same-Origin gilt auch für andere Daten (WebFonts, Bilder / Videos, die mit drawImage () gezeichnet wurden ...).
- Es ist weder sehr elegant noch lesbar.
Das Mitnehmen ist, dass es heutzutage nicht nötig ist, es zu benutzen .
JSONP ist der Trick, um JSON-Daten von einem anderen Server abzurufen. Wir verstoßen jedoch gegen dasselbe Sicherheitsprinzip (Same-Origin), wenn wir andere Arten von standortübergreifendem Material benötigen.
Sie sollten hier über CORS lesen , aber das Wesentliche ist:
Cross-Origin Resource Sharing (CORS) ist ein Mechanismus, der mithilfe zusätzlicher HTTP-Header Browser anweist, einer Webanwendung, die an einem Ursprung ausgeführt wird, Zugriff auf ausgewählte Ressourcen eines anderen Ursprungs zu gewähren. Eine Webanwendung führt eine originensübergreifende HTTP-Anforderung aus, wenn sie eine Ressource anfordert, die einen anderen Ursprung (Domäne, Protokoll oder Port) als ihre eigene hat.
* Der Ursprung wird durch drei Dinge definiert: Protokoll , Port und Host . So ist zum Beispiel https://web.com
ein anderer Ursprung als http://web.com
(anderes Protokoll) und https://web.com:8081
(anderer Port) und offensichtlich https://thatotherweb.net
(anderer Host)