Maison  >  Article  >  interface Web  >  Explication détaillée basée sur le principe JSONP

Explication détaillée basée sur le principe JSONP

小云云
小云云original
2018-01-05 10:18:401421parcourir

Cet article recommande principalement une analyse basée sur les principes JSONP. Il a une bonne valeur de référence et j'espère qu'il sera utile à tout le monde. Suivons l'éditeur pour y jeter un œil, j'espère que cela pourra aider tout le monde.

Avant-propos

Le premier projet avec lequel je suis entré en contact depuis que je travaille était la séparation du front-end et du back-end. Les fichiers statiques front-end ont leurs propres noms de domaine indépendants, et le. les données sont obtenues via l'interface pour le rendu et d'autres opérations.

Il n'est pas nécessaire d'élaborer sur les méthodes inter-domaines. Il suffit de rechercher et il y en aura beaucoup, mais les méthodes les plus couramment utilisées sont jsonp et CORS. jsonp se concentre sur le front-end, qui peut être considéré comme le front-end. Les compétences de piratage CORS sont plus importantes que le back-end, et le serveur doit être davantage configuré.

Cet article analyse le principe d'implémentation de jsonp.

Principe de base

Le principe de base est facile à expliquer. Certaines balises dans les pages HTML ne sont pas soumises à des restrictions inter-domaines, telles que img, script, link, etc. Si nous mettons les données dont nous avons besoin dans un fichier js, nous pouvons alors dépasser la limitation de même origine du navigateur.

Créer une balise de script

Les éléments de script dynamiques sont mentionnés dans "JavaScript haute performance". L'auteur écrit :

Le téléchargement du fichier commence lorsque l'élément est ajouté au fichier. page. Le point clé de cette technologie est que chaque fois qu'un téléchargement est lancé, le téléchargement et l'exécution du fichier ne bloquent pas les autres processus sur la page.

2. Lorsque vous utilisez des nœuds de script dynamiques pour télécharger des fichiers, le code renvoyé sera généralement exécuté immédiatement (sauf pour Firefox et Oprea, qui attendront la fin de l'exécution de tous les nœuds de script dynamiques précédents.) Lorsque le script s'exécute. lui-même, ce mécanisme Cela fonctionne bien.

La citation 1 garantit que le thread principal ne sera pas bloqué lors des requêtes JSONP. La citation 2 garantit qu'il n'y aura pas d'erreurs lorsque le code JSONP s'exécutera immédiatement après la fin du chargement.

callback

Après avoir reçu la requête GET, le serveur détermine généralement s'il existe un paramètre de rappel. Si tel est le cas, il doit ajouter un nom de méthode et des parenthèses en dehors des données renvoyées. Par exemple, si la requête suivante est initiée :

http://www.a.com/getSomething?callback=jsonp0

alors le serveur renverra le contenu suivant :

jsonp0({code:200,data:{}})

Évidemment, puisqu'il s'agit du contenu contenu dans le Script chargé dynamiquement tag, Alors c'est un morceau de code auto-exécutable dans ce code - jsonp0.

Bien sûr, s'il y a exécution, il faut d'abord la créer, sinon une erreur sera signalée. Cette étape de création doit être exécutée avant l'appel.

L'implémentation spécifique est la suivante :

function jsonp (url, successCallback, errorCallback, completeCallback) {

 // 声明对象,需要将函数声明至全局作用域
 window.jsonp0 = function (data) {
  successCallback(data);
  if (completeCallback) completeCallback();
 }
 // 创建script标签,并将url后加上callback参数
 var 
  script = document.createElement('script')
  , url = url + (url.indexOf('?') == -1 ? '?' : '&') + 'callback=jsonp0'
 ;
 script.src = url;
 document.head.parentNode.insertBefore(script, document.head);
 // 等到script加载完毕以后,就会自己执行
}

Ce qui précède complète essentiellement le cœur d'une méthode jsonp À ce stade, jsonp0 est une fonction que nous avons déclarée si le serveur renvoie normalement. , la fonction jsonp0 sera exécutée et le rappel successCallback à l'intérieur sera également exécuté.

Améliorez-le

Dans les situations réelles, de nombreuses requêtes jsonp sont généralement appelées en même temps,

Donc, puisque jsonp0 peut répondre à nos besoins, pourquoi voyons-nous souvent Qu'en est-il des codes qui ajoutent jsonp1, jsonp2, etc. dans l'ordre ?

En effet, les requêtes peuvent être effectuées de manière asynchrone. Lorsque la méthode jsonp est exécutée pour la première fois, window.jsonp0 est la fonction A. À ce moment, le fichier js est chargé. Lorsque js n'est pas chargé, la méthode jsonp est à nouveau appelée. fonction B. Ensuite, une fois les deux js chargés, le deuxième rappel sera exécuté.

Il faut donc faire une distinction dans le nom du rappel, et l'accumulation peut répondre aux besoins.

Modifiez le code :

var jsonpCounter = 0;
function jsonp (url, successCallback, errorCallback, completeCallback) {
 
 var jsId = 'jsonp' + jsonpCounter++;
 
 // 声明对象,需要将函数声明至全局作用域
 window[jsId] = function (data) {
  successCallback(data);
  if (completeCallback) completeCallback();
  clean();
 }
 // 创建script标签,并将url后加上callback参数
 var 
  script = document.createElement('script')
  , url = url + (url.indexOf('?') == -1 ? '?' : '&') + 'callback=' + jsId
 ;
 script.src = url;
 document.head.parentNode.insertBefore(script, document.head);
 // 等到script加载完毕以后,就会自己执行
 
 //在执行完我们这个方法以后,会有很多script标签出现在head之前,我们需要手动的删除掉他们。
 function clean () {
  script.parentNode.removeChild(script);
  window[jsId] = function(){};
 }
}

Après avoir ajouté l'accumulation et le nettoyage, il reste encore un endroit important à gérer, qui est le rappel d'erreur. Normalement, lorsque nous demandons jsonp, nous définissons généralement un délai d'attente. Si ce délai est dépassé, une exception de délai d'attente sera levée.

L'implémentation est la suivante :

var jsonpCounter = 0;
function jsonp (url, successCallback, errorCallback, completeCallback, timeout) {
 // 略去上面写过的代码
 var 
  timeout = timeout || 10000
  , timer
 ;
 if (timeout) {
  timer = setTimeout(function () {
   if (errorCallback) {
    errorCallback(new Error('timeout'));
   }
   clean();
  }, timeout)
 }
 
 function clean () {
  script.parentNode.removeChild(script);
  window[jsId] = function(){};
  if (timer) clearTimeout(timer);
 }
}

De cette façon, toutes les fonctions de jsonp sont fondamentalement terminées, et le reste peut nécessiter quelques modifications compatibles pour être considéré comme un ensemble complet méthode jsonp.

REFER

"JavaScript haute performance"

Une implémentation de jsonp sur npm, JSONP

Recommandations associées :

Résumé de la façon d'utiliser Ajax et jsonp

Comment le JS natif implémente AJAX, JSONP

Principes Jsonp et méthodes d'implémentation simples

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn