JSONP: Die Geheimwaffe der Frontend-Entwickler von damals
\nStellen Sie sich vor, Sie sind ein Webentwickler im Jahr 2010. Sie müssen Daten von einem fremden Server abrufen, zum Beispiel eine Wettervorhersage oder Wechselkurse. Sie schreiben eine einfache fetch-Anfrage, aber in der Browserkonsole erscheint ein roter Fehler: „No 'Access-Control-Allow-Origin' header is present“. Kommt Ihnen bekannt vor?
Dies ist die Same-Origin Policy (Gleichherkunftsrichtlinie), die Ihr JavaScript daran hindert, die Grenzen der eigenen Domain zu verlassen. Aber wie funktionierten dann Wetter-Widgets, „Teilen“-Buttons und Besucherzähler? Die Antwort ist einfach: Sie verwendeten JSONP – einen cleveren Trick, über den wir heute sprechen werden.
\nIn diesem Artikel beantworten wir die beliebte Frage von Stack Overflow: „What is JSONP, and why was it created?“ – in einfacher Sprache, mit Codebeispielen und ohne überflüssige Theorie.
\n\n1. Das Problem: Warum blockiert der Browser Anfragen?
\nDer Browser ist paranoid. Er schützt den Benutzer vor XSS-Angriffen und Datendiebstahl. Die Same-Origin Policy erlaubt JavaScript nur dann, Antworten zu lesen, wenn sie von derselben Domain, demselben Protokoll und demselben Port stammen.
\nBeispiel für eine Blockierung:
\n// Dieser Code löst einen CORS-Fehler aus\nfetch('https://api.distant-server.com/data')\n .then(response => response.json())\n .then(data => console.log(data));\nEs gibt jedoch eine Ausnahme: <script>-Tags. Der Browser lädt Skripte von beliebigen Domains problemlos! Genau diese Hintertür nutzt JSONP.
\n\n2. Die Lösung: JSONP – JSON mit Padding
\nJSONP (JSON with Padding) ist weder eine Technologie noch ein Datenformat, sondern ein Pattern (Workaround), das die Same-Origin Policy über den <script>-Tag umgeht.
Die Idee ist einfach: Anstatt eine Anfrage über XMLHttpRequest zu stellen, erstellen wir dynamisch ein <script>-Element, geben die URL des Servers an, und der Server gibt kein JSON zurück, sondern JavaScript-Code, der unsere Funktion mit den Daten aufruft.
Wie normales JSON aussieht:
\n// Serverantwort (normales JSON)\n{"name": "PythonLib", "topic": "JSONP"}\n\nWie JSONP aussieht:
\n// Serverantwort (JSONP)\nmyCallback({"name": "PythonLib", "topic": "JSONP"});\nDer Unterschied ist enorm: Im zweiten Fall verpackt der Server die Daten in einen Aufruf der Funktion myCallback. Das ist genau das Padding (die Verpackung).
3. Praxis: Eine JSONP-Anfrage selbst schreiben
\nLassen Sie uns einen JSONP-Client in reinem JavaScript implementieren. Das hilft, die Magie zu verstehen.
\n\nfunction jsonp(url, callbackName) {\n // 1. Globale Funktion (Callback) erstellen\n window[callbackName] = function(data) {\n console.log('Daten empfangen:', data);\n delete window[callbackName]; // Aufräumen\n document.body.removeChild(script);\n };\n\n // 2. Script-Tag erstellen\n const script = document.createElement('script');\n script.src = `${url}?callback=${callbackName}`; // Callback-Namen übergeben\n script.onerror = function() {\n console.error('Fehler beim Laden von JSONP');\n delete window[callbackName];\n document.body.removeChild(script);\n };\n\n // 3. Zum DOM hinzufügen – der Browser lädt und führt das Skript sofort aus\n document.body.appendChild(script);\n}\n\n// Verwendung:\njsonp('https://api.example.com/data', 'handleData');\nSo funktioniert es Schritt für Schritt:
\n- \n
- Wir erstellen eine globale Funktion
handleData. \n - Wir fügen einen
<script>-Tag mit der Server-URL hinzu. In der URL übergeben wir den Parameter?callback=handleData. \n - Der Server, der JSONP unterstützt, sieht den Parameter
callbackund gibt kein JSON zurück, sondern JavaScript:handleData({...}). \n - Der Browser führt dieses Skript aus, unsere Funktion wird aufgerufen, und wir erhalten die Daten. \n
4. Warum ist JSONP böse? (Nachteile)
\nWenn Sie gedacht haben: „Cool, das werde ich überall verwenden“ –