TL; DR
JSONP est une vieille astuce inventée pour contourner la restriction de sécurité qui nous interdit d'obtenir des données JSON à partir d'un serveur différent (une origine différente * ).
L'astuce fonctionne en utilisant une <script>
balise qui demande le JSON de cet endroit, par exemple :,{ "user":"Smith" }
mais enveloppé dans une fonction, le JSONP réel ("JSON avec remplissage"):
peopleDataJSONP({"user":"Smith"})
Le recevoir sous cette forme nous permet d'utiliser les données au sein de notre peopleDataJSONP
fonction. JSONP est une mauvaise pratique , ne l'utilisez pas (lire ci-dessous)
Le problème
Supposons que nous naviguons ourweb.com
et que nous voulons obtenir des données JSON (ou vraiment des données brutes) anotherweb.com
. Si nous devions utiliser la requête GET (comme XMLHttpRequest
un fetch
appel, $.ajax
etc.), notre navigateur nous dirait que ce n'est pas autorisé avec cette horrible erreur:
Comment obtenir les données que nous voulons? Eh bien, les <script>
balises ne sont pas soumises à toute cette restriction de serveur (origine *)! C'est pourquoi nous pouvons charger une bibliothèque comme jQuery ou Google Maps à partir de n'importe quel serveur, tel qu'un CDN, sans aucune erreur.
Point important : si vous y réfléchissez, ces bibliothèques sont du code JS réel et exécutable (généralement une fonction massive avec toute la logique à l'intérieur). Mais des données brutes? Les données JSON ne sont pas du code . Il n'y a rien à courir; ce sont juste des données simples.
Par conséquent, il n'y a aucun moyen de gérer ou de manipuler nos précieuses données. Le navigateur téléchargera les données pointées par notre <script>
tag et lors du traitement, il se plaindra à juste titre:
wtf est cette {"user":"Smith"}
merde que nous avons chargée? Ce n'est pas du code. Je ne peux pas calculer, erreur de syntaxe!
Le hack JSONP
La manière ancienne / hacky d'utiliser ces données? Nous avons besoin de ce serveur pour l'envoyer avec une certaine logique, donc lorsqu'il est chargé, votre code dans le navigateur pourra utiliser lesdites données. Le serveur étranger nous envoie donc les données JSON à l'intérieur d'une fonction JS. Les données elles-mêmes sont configurées comme entrée de cette fonction. Cela ressemble à ceci:
peopleDataJSONP({"user":"Smith"})
ce qui en fait du code JS que notre navigateur analysera sans se plaindre! Exactement comme avec la bibliothèque jQuery. Maintenant, pour l'obtenir comme ça, le client "demande" au serveur compatible JSONP de le faire, généralement comme ceci:
<script src="https://anotherweb.com/api/data-from-people.json?myCallback=peopleDataJSONP"></script>
Notre navigateur recevra le JSONP avec ce nom de fonction, donc nous avons besoin d'une fonction avec le même nom dans notre code, comme ceci:
const peopleDataJSONP = function(data){
alert(data.user); // "Smith"
}
Ou comme ça, même résultat:
function peopleDataJSONP(data){
alert(data.user); // "Smith"
}
Le navigateur va télécharger le JSONP et l'exécuter, qui appelle notre fonction , où l'argument data
sera notre JSON. Nous pouvons maintenant faire avec nos données tout ce que nous voulons.
N'utilisez pas JSONP, utilisez CORS
JSONP est un hack intersite avec quelques inconvénients:
- Nous ne pouvons effectuer que des requêtes GET
- Comme il s'agit d'une demande GET déclenchée par une simple balise de script, nous n'obtenons pas d'erreurs utiles ni d'informations de progression
- Il existe également des problèmes de sécurité, comme l'exécution de votre code JS client qui pourrait être changé en une charge utile malveillante.
- Cela ne résout que le problème avec les données JSON, mais la politique de sécurité de même origine s'applique aux autres données (WebFonts, images / vidéo dessinées avec drawImage () ...)
- Ce n'est ni très élégant ni lisible.
Le point à retenir est qu'il n'est pas nécessaire de l'utiliser de nos jours .
JSONP est l'astuce pour obtenir des données JSON à partir d'un autre serveur, mais nous violerons le même principe de sécurité (Same-Origin) si nous avons besoin d'autres types de choses intersites.
Vous devriez lire sur CORS ici , mais l'essentiel est:
Le partage de ressources entre origines (CORS) est un mécanisme qui utilise des en-têtes HTTP supplémentaires pour indiquer aux navigateurs de donner à une application Web fonctionnant à une origine, l'accès aux ressources sélectionnées d'une origine différente. Une application Web exécute une requête HTTP d'origine croisée lorsqu'elle demande une ressource qui a une origine (domaine, protocole ou port) différente de la sienne.
* l'origine est définie par 3 choses: protocole , port et hôte . Ainsi, par exemple, https://web.com
est une origine différente de http://web.com
(protocole différent) et https://web.com:8081
(port différent) et évidemment https://thatotherweb.net
(hôte différent)