Avant-propos
La première fois que j'ai entendu parler de jsonp, c'était il y a 2 ans. A cette époque, je travaillais sur un module de loterie pour une page d'événement. J'avais besoin d'obtenir une probabilité du serveur. Je n'ai rien compris à l'époque. Mon collègue m'a dit d'utiliser ajax, alors j'ai utilisé ajax. a dit que le dataType devait être changé en jsonp, je l'ai donc changé en jsonp. La page d'activité était donc terminée et je n'ai plus jamais rencontré jsonp. Pendant cette période, j'ai toujours pensé que jsonp était étroitement lié à ajax, et qu'il s'agissait d'une forme spéciale inter-domaines de xhr... Jusqu'à une interview il y a un mois, J'ai posé des questions sur jsonp. J'ai été torturé à mort, alors j'ai décidé de jeter un œil à jsonp. Eh bien, il s'avère que jsonp n'est pas difficile.
Pourquoi utiliser jsonp ?
Je pense que tout le monde est familier avec le cross-domain et est également familier avec la stratégie de même origine. Quoi, tu n'en as pas entendu parler ? Ce n’est pas grave, puisque nous l’expliquons en termes simples, commençons par le début.
Supposons que j'écrive une page d'index et qu'il y ait une requête dans la page. La requête concerne des données json (je ne connais pas l'introduction JSON et le résumé de l'utilisation des données json). code suivant :
<script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script> <script type="text/javascript"> $.ajax({ url: 'http://localhost/a.json', dataType: "json", success: function (data) { console.log(data); } }) </script> { "name": "hanzichi", "age": 10 }
L'affiche a placé les deux fichiers dans le dossier www sous wamp. La requête ajax n'a pas traversé les domaines et les résultats ont été parfaitement obtenus :
Mais que se passe-t-il si mon fichier json et mon fichier d'index ne se trouvent pas dans le même domaine, c'est-à-dire inter-domaines (si vous ne comprenez pas inter-domaines, veuillez vous référer à la politique de même origine de JavaScript) ?
Essayez d'ouvrir un nouveau port Apache sous Wamp (si vous ne savez pas comment l'ouvrir, vous pouvez vous référer à l'utilisation de l'accès multi-port sous WampServer), et placez le fichier json dans le dossier du port de service ( le numéro de port défini par l'affiche est 8080, la valeur par défaut est le port 80), essayez d'envoyer une demande :
<script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script> <script type="text/javascript"> $.ajax({ url: 'http://localhost:8080/a.json', dataType: "json", success: function (data) { console.log(data); } }) </script>
Évidemment, l'invite est interdomaine ! Ce qu'il faut faire? En ce moment, jsonp est sur le point d'agir !
Balise de script magique
La balise script est étroitement liée à jsonp, mais xhr ou ajax au sens traditionnel n'a rien à voir avec ça !
Ensuite, en regardant le code index.html ci-dessus, nous voyons que la page fait référence au chemin jquery de Baidu cdn. Nous semblons être habitués à cette méthode, mais si nous y réfléchissons bien, la balise script est complètement croisée. -domain..Oui, le cœur de l'implémentation de jsonp est d'utiliser la capacité inter-domaines des balises de script ! Nous avons donc eu une idée et il semblait que nous pouvions le faire, générer dynamiquement une balise de script, attribuer l'url json à l'attribut src du script, puis insérer la balise de script dans le dom...
<body> <script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script> <script type="text/javascript"> var s = document.createElement('script'); s.src = 'http://localhost:8080/a.json'; document.body.appendChild(s); </script> </body>
Nous avons créé une balise de script et le contenu enveloppé dans la balise correspond aux données json requises, mais l'erreur est la suivante :
La raison est que les données json ne sont pas une déclaration js légale. Mettre les données json ci-dessus dans une fonction de rappel est le moyen le plus simple :
<body> <script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script> <script type="text/javascript"> function jsonpcallback(json) { console.log(json); } var s = document.createElement('script'); s.src = 'http://localhost:8080/a.json'; document.body.appendChild(s); </script> </body> jsonpcallback({ "name": "hanzichi", "age": 10 });
Bien entendu, le fichier a.json n'a pas besoin d'être nommé de cette façon, et il n'y aura aucun problème s'il est modifié en a.js.
Il en va de même si vous interagissez avec le serveur, comme avec php :
<body> <script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script> <script type="text/javascript"> function jsonpcallback(json) { console.log(json); } var s = document.createElement('script'); s.src="http://localhost:8080/test.php?callback=jsonpcallback"; document.body.appendChild(s); </script> </body> <?php $jsondata = '{ "name": "hanzichi", "age": 10 }'; echo $_GET['callback'].'('.$jsondata.')'; ?>
Il convient de noter que quelle que soit la forme à laquelle ressemble l'URL fournie par jsonp (c'est-à-dire le src de la balise de script générée dynamiquement), le retour final généré est un morceau de code js.
Encapsulation de jsonp par JQuery
Afin de faciliter le développement, jq encapsule également jsonp dans la méthode ajax.
<script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script> <script type="text/javascript"> $.ajax({ url: 'http://localhost:8080/a.json', dataType: 'jsonp', jsonpCallback: 'CallBack', success: function (data) { console.log(data); } }); </script> CallBack({ "name": "hanzichi", "age": 10 });
Le code ci-dessus concerne le cas où le nom de la fonction de rappel est écrit en dur dans le fichier de requête. Étant donné que la requête est un fichier json, json n'est pas un langage dynamique côté serveur et ne peut pas être analysé. S'il s'agit de PHP ou d'un autre langage côté serveur, il n'est pas nécessaire de coder en dur le nom de la fonction, comme suit :
<script src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script> <script type="text/javascript"> $.ajax({ url: 'http://localhost:8080/test.php', dataType: 'jsonp', success: function (data) { console.log(data); } }); </script> <?php $jsondata = '{ "name": "hanzichi", "age": 10 }'; echo $_GET['callback'].'('.$jsondata.')'; ?>
Bien entendu, il existe plusieurs méthodes d'encapsulation similaires :
// 1 $.getJSON("http://localhost:8080/test.php?callback=?", function(data) { console.log(data); }); // 2 $.get('http://localhost:8080/test.php', function(data) { console.log(data); }, 'jsonp');
Il convient de noter que l'URL de l'adresse de requête de la méthode getJSON doit apporter callback=?, car lorsque jq encapsule cette méthode, il n'y a pas de variable de fonction de rappel par défaut nommée callback, donc $_GET['callback'] en php La valeur de la variable est introuvable.
Il n'est pas nécessaire de spécifier le paramètre de rappel dans l'URL générale de la méthode jq. Pour jsonp dans jQuery, le paramètre de rappel est ajouté automatiquement. Par défaut, le paramètre de rappel dans la requête jsonp générée par jQuery est sous la forme callback=jQuery200023559735575690866_1434954892929. Ce nom apparemment aléatoire correspond à la fonction de traitement du succès, il n'est donc généralement pas nécessaire de le traiter spécialement. 2. Si vous souhaitez noter le nom du rappel, vous pouvez vous référer à ce qui précède.
Résumé
En raison de la restriction de la politique de même origine, XmlHttpRequest autorise uniquement les requêtes de ressources à partir de la source actuelle (nom de domaine, protocole, port). Afin d'implémenter des requêtes inter-domaines, vous pouvez implémenter des requêtes inter-domaines via). la balise de script, puis affichez les données JSON sur le serveur et exécutez-les. La fonction de rappel résout les demandes de données inter-domaines, qui sont le cœur de jsonp.
Principe jsonp :
1. Enregistrez d'abord un rappel sur le client, puis transmettez le nom du rappel au serveur.
2. Le serveur génère d'abord des données json. Générez ensuite une fonction en utilisant la syntaxe javascript, et le nom de la fonction est le paramètre jsonp transmis. Enfin, les données json sont directement placées dans la fonction en tant que paramètre, générant ainsi un document de syntaxe js et le renvoyant au client.
3. Le navigateur client analyse la balise de script et exécute le document javascript renvoyé. A ce moment, les données sont transmises en paramètre à la fonction de rappel prédéfinie par le client (Exécution dynamique de la fonction de rappel)
La différence entre json et jsonp, la différence entre ajax et jsonp
Bien qu'il n'y ait qu'une seule lettre de différence entre json et jsonp, ils ne sont pas liés les uns aux autres.
json est un format d'échange de données léger.
jsonp est un protocole d'échange de données inter-domaines.
Avantages de json : (1) Il est extrêmement simple à transmettre sur la base de texte brut, (2) Le format de données léger est adapté à la transmission sur Internet, (3) Il est facile à écrire et à analyser.
La différence entre ajax et jsonp :
La même chose : ils demandent tous les deux une url
Différence : le cœur d'Ajax est d'obtenir du contenu via xmlHttpRequest
Le cœur de jsonp est d'ajouter dynamiquement la balise