JSONP : L'arme secrète du développeur front-end d'autrefois
\nImaginez que vous êtes un développeur web en 2010. Vous devez récupérer des données depuis un serveur tiers, par exemple les prévisions météo ou le taux de change. Vous écrivez une simple requête fetch, mais dans la console du navigateur apparaît une erreur rouge : « No 'Access-Control-Allow-Origin' header is present ». Cela vous dit quelque chose ?
C'est la Same-Origin Policy (politique de même origine) qui empêche votre JavaScript d'accéder à des domaines autres que le vôtre. Mais comment fonctionnaient alors les widgets météo, les boutons « Partager » et les compteurs de visites ? La réponse est simple : ils utilisaient JSONP — une astuce ingénieuse dont nous allons parler aujourd'hui.
\nDans cet article, nous répondrons à la question populaire de Stack Overflow : « What is JSONP, and why was it created? » — en termes simples, avec des exemples de code et sans théorie superflue.
\n\n1. Le problème : Pourquoi le navigateur bloque-t-il les requêtes ?
\nLe navigateur est paranoïaque. Il protège l'utilisateur contre les attaques XSS et le vol de données. La Same-Origin Policy autorise JavaScript à lire les réponses uniquement depuis le même domaine, protocole et port.
\nExemple de blocage :
\n// Ce code provoquera une erreur CORS\nfetch('https://api.distant-server.com/data')\n .then(response => response.json())\n .then(data => console.log(data));\nMais il y a une exception : les balises <script>. Le navigateur charge tranquillement les scripts depuis n'importe quel domaine ! C'est cette faille qu'utilise JSONP.
\n\n2. La solution : JSONP — JSON avec Padding
\nJSONP (JSON with Padding) n'est ni une technologie ni un format de données, mais un patron de conception (une rustine) qui contourne la Same-Origin Policy via la balise <script>.
L'idée est simple : au lieu d'effectuer une requête via XMLHttpRequest, nous créons dynamiquement un élément <script>, pointons vers l'URL du serveur, et le serveur renvoie non pas du JSON, mais du code JavaScript qui appelle notre fonction avec les données.
À quoi ressemble un JSON normal :
\n// Réponse du serveur (JSON normal)\n{"name": "PythonLib", "topic": "JSONP"}\n\nÀ quoi ressemble un JSONP :
\n// Réponse du serveur (JSONP)\nmyCallback({"name": "PythonLib", "topic": "JSONP"});\nLa différence est colossale : dans le second cas, le serveur encapsule les données dans un appel à la fonction myCallback. C'est ce fameux padding (emballage).
3. Pratique : Écrire une requête JSONP à la main
\nImplémentons un client JSONP en JavaScript pur. Cela vous aidera à comprendre la magie.
\n\nfunction jsonp(url, callbackName) {\n // 1. Créer une fonction globale (callback)\n window[callbackName] = function(data) {\n console.log('Données reçues :', data);\n delete window[callbackName]; // Nettoyer après soi\n document.body.removeChild(script);\n };\n\n // 2. Créer la balise script\n const script = document.createElement('script');\n script.src = `${url}?callback=${callbackName}`; // Transmettre le nom du callback\n script.onerror = function() {\n console.error('Erreur de chargement JSONP');\n delete window[callbackName];\n document.body.removeChild(script);\n };\n\n // 3. Ajouter au DOM — le navigateur charge et exécute immédiatement le script\n document.body.appendChild(script);\n}\n\n// Utilisation :\njsonp('https://api.example.com/data', 'handleData');\nComment cela fonctionne étape par étape :
\n- \n
- Nous créons une fonction globale
handleData. \n - Nous ajoutons une balise
<script>avec l'URL du serveur. Dans l'URL, nous transmettons le paramètre?callback=handleData. \n - Le serveur supportant JSONP voit le paramètre
callbacket renvoie non pas du JSON, mais du JavaScript :handleData({...}). \n - Le navigateur exécute ce script, notre fonction est appelée, et nous recevons les données. \n
4. Pourquoi JSONP est-il un mal ? (Inconvénients)
\nSi vous avez pensé : « Génial, je vais l'utiliser partout