Maison  >  Article  >  interface Web  >  Explication détaillée de la prise en charge ajax personnalisée pour l'encapsulation de composants inter-domaines

Explication détaillée de la prise en charge ajax personnalisée pour l'encapsulation de composants inter-domaines

小云云
小云云original
2018-02-09 09:49:28969parcourir

Cet article vous donne principalement une analyse détaillée des points de connaissances liés à la prise en charge ajax personnalisée pour l'encapsulation de composants inter-domaines. Les amis qui sont intéressés par cela peuvent s'y référer et espérer aider tout le monde.

Analyse Class.create()

Imiter un prototype pour créer un héritage de classe

var Class = {
  create: function () {
    var c = function () {
      this.request.apply(this, arguments);
    }
    for (var i = 0, il = arguments.length, it; i < il; i++) {
      it = arguments[i];
      if (it == null) continue;
      Object.extend(c.prototype, it);
    }
    return c;
  }
};
Object.extend = function (tObj, sObj) { 
  for (var o in sObj) {
    tObj[o] = sObj[o];
  }
  return tObj;
};

Définition ajax : ZIP_Ajax=Class.create();

La méthode create renvoie une requête de constructeur, qui équivaut à var ZIP_Ajax= function(){ this.request.apply(this, arguments }; Exécuter un processus de construction équivaut à confier la tâche de constructeur à la méthode de requête. This.request est ici la méthode de l'instance ZIP_Ajax, et cela pointe vers l'instance ZIP_Ajax This after apply pointe vers ZIP_Ajax Enfin selon le nouveau mot-clé. , cela pointe en fait vers la classe ZIP_Ajax. Avec la définition de la classe ZIP_Ajax, vous pouvez ensuite définir sa méthode :

Explication détaillée de XMLHttpRequest :

XMLHttpRequest n'est pas une technologie mais une fonction intégrée aux navigateurs grand public Accès complet. aux objets de protocole http. La plupart des requêtes http traditionnelles sont basées sur la soumission d'un formulaire et demandent http, puis renvoient un formulaire. Bien que XMLHttpRequest prenne en charge les requêtes synchrones, le plus grand avantage est qu'il prend en charge la transmission asynchrone pour recevoir des données. La création d'une nouvelle requête ajax revient en fait à instancier un objet XMLHttpRequest. Présentez brièvement les principaux événements et méthodes :

Événement readystatechange :

Lorsque XMLHttpRequest envoie une requête http, un événement readystatechange sera déclenché. L'événement renvoie cinq valeurs 0. , 1 et 2 représentent respectivement la création de XMLHttpRequest, l'achèvement de l'initialisation de XMLHttpRequest et l'envoi de la requête 3 représente que la réponse n'est pas terminée (c'est-à-dire que seules les données d'en-tête de réponse sont reçues). réponse complète.

Le statut renvoyé indique le code d'état renvoyé par le serveur :

Les codes couramment utilisés sont 200 indiquant un retour réussi des données, 301 redirection permanente et 302 redirection temporaire. (pas de sécurité) 304 lit les données mises en cache, 400 indique une erreur de syntaxe dans la demande, 403 indique que le serveur rejette la demande, 404 indique que la ressource de page Web demandée n'existe pas, 405 ne peut pas trouver le serveur à l'emplacement spécifié, 408 indique que la demande a expiré, 500 indique une erreur interne du serveur et 505 indique que le serveur La version du protocole http demandée n'est pas prise en charge.

200-300 signifie succès, 300-400 signifie redirection, 400-500 signifie que le contenu ou le format de la demande ou le corps de la demande est trop volumineux, provoquant une erreur, 500+ signifie une erreur interne du serveur

méthode open :

open reçoit trois paramètres : type de requête (get, post, head, etc.), url, synchrone ou asynchrone

méthode d'envoi :

Lorsque la requête est prête, la méthode d'envoi sera déclenchée, et le contenu envoyé est les données demandées (s'il s'agit d'une requête get, le paramètre est nul ;

Une fois la requête réussie, le succès sera exécuté Méthode personnalisée dont le paramètre est return data

ajax cross-domain :

Qu'est-ce que cross ; -domaine ?

Si deux sites Lorsque www.a.com souhaite demander des données à www.b.com, des problèmes inter-domaines surviennent en raison de noms de domaine incohérents, même si les noms de domaine sont les mêmes. de même, si les ports sont différents, il y aura des problèmes inter-domaines (pour cette raison, js ne peut que rester là et regarder. ). Déterminer s'il s'agit d'un inter-domaine n'est déterminé que par window.location.protocol+window.location. .host. Par exemple, http://www.baidu.com.

Il existe plusieurs façons de résoudre les problèmes inter-domaines avec js Solution ? . document.domain+iframe

Pour les requêtes avec le même domaine principal mais des sous-domaines différents, le nom de domaine + iframe peut être utilisé comme solution. L'idée spécifique est qu'il y a deux fichiers ab différents sous le nom de domaine. www.a.com/a.html

et hi.a.com/b.html, on peut ajouter document.domain=" aux deux fichiers html a.com", puis créer une iframe dans le fichier a pour contrôler le contenuDocument de l'iframe, afin que les deux fichiers puissent communiquer. Par exemple :

a sur www.a.com. 🎜>
Dans le fichier b.html sur hi.a.com

document.domain="a.com";
document.domain="a.com";
  var selfFrame=document.createElement("iframe");
  selfFrame.src="http://hi.a.com/b.html";
  selfFrame.style.display="none";
  document.body.appendChild(selfFrame);
  selfFrame.onload=function(){
    var doc=selfFrame.contentDocument||selfFrame.contentWindow.document;//得到操作b.html权限
    alert(doc.getElementById("ok_b").innerHTML());//具体操作b文件中元素
  }


Problèmes :

1. Sécurité. Lorsqu'un site (hi.a.com) est attaqué, un autre site (www.a.com) provoquera une vulnérabilité de sécurité. 2. Si vous introduisez plusieurs iframes. capable de faire fonctionner toutes les iframes, vous devez définir le même domaine

2. Créer dynamiquement des scripts (la légendaire méthode jsonp)

Les navigateurs interdisent le croisement d'accès au domaine, mais c'est le cas. Il n'est pas interdit de référencer des fichiers js d'autres noms de domaine dans la page, et les méthodes introduites dans les fichiers js peuvent être exécutées. Sur cette base, nous pouvons réaliser une communication interdomaine complète en créant des méthodes de nœud de script. Les étapes d'implémentation sont :

a. Charger dynamiquement un script sur la page de l'initiateur de la requête. L'url du script pointe vers le backend du destinataire. La méthode javascript renvoyée par l'adresse sera exécutée par l'initiateur. . L'URL peut transmettre des paramètres et ne prend en charge que les paramètres de soumission.


b. Lors du chargement du script, appelez la méthode js inter-domaines pour le traitement de rappel (jsonp).


Par exemple :


Initiateur


Récepteur :

Le récepteur n'a besoin de renvoyer qu'une seule exécution fonction, la fonction d'exécution est le rappel dans la requête et attribue des paramètres.
function uploadScript(options){
  var head=document.getElementsByTagName("head")[0];
  var script=document.createElement("script");
  script.type="text/javasctipt";
  options.src += &#39;?callback=&#39; + options.callback;
  script.src=options.src;
  head.insertBefore(script,head.firstChild);
}
function callback(data){}
window.onload=function(){//调用
  uploadScript({src:"http://e.com/xxx/main.ashx",callback:callback})
}


3. Utilisez html5 postMessage :


L'une des nouvelles fonctionnalités de HTML5 est la transmission de messages entre documents, qui est désormais prise en charge et utilisée par la plupart des navigateurs (y compris ie8+). ), qui prend en charge la messagerie Web en temps réel et ne présente aucun problème entre domaines. postMessage est généralement utilisé avec iframe.

举例如下:

父页面:

<iframe id="myPost" src="http//www.a.com/main.html"></iframe>
window.onload=function(){
  document.getElementById("myPost").contentWindow.postMessage("显示我","http://www.a.com")
  //第二个参数表示确保数据发送给适合域名的文档
}
a.com/main.html页面:
window.addEventListener("message",function(event){
  if(event.origin.indexOf("a.com")>-1){
    document.getElementById("textArea").innerHTML=event.data;
  }
},false)
<body>
  <p>
    <span id="textArea"></span>
  </p>
</body>

这样在父页面加载完成后main.html页面的textArea部分就会显示"显示我"三个字

ajax方法封装code:

ZIP_Ajax.prototype={
  request:function(url options){
    this.options=options;
    if(options.method=="jsonp"){//跨域请求
      return this.jsonp();
    }
    var httpRequest=this.http();
    options=Object.extend({method: 'get',
      async: true},options||{});
    
    if(options.method=="get"){
      url+=(url.indexOf('?')==-1?'?':'&')+options.data;
      options.data=null;
    }
    httpRequest.open(options.method,url,options.async);
    if (options.method == 'post') {
      httpRequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
    }
    httpRequest.onreadystatechange = this._onStateChange.bind(this, httpRequest, url, options);
    httpRequest.send(options.data || null);//get请求情况下data为null
    return httpRequest;
  },
  jsonp:function(){
    jsonp_str = 'jsonp_' + new Date().getTime();
    eval(jsonp_str + ' = ' + this.options.callback + ';');    
    this.options.url += '?callback=' + jsonp_str;
    for(var i in this.options.data) {
      this.options.url += '&' + i + '=' + this.options.data[i];
    } 
    var doc_head = document.getElementsByTagName("head")[0],
      doc_js = document.createElement("script"),
      doc_js.src = this.options.url;
    doc_js.onload = doc_js.onreadystatechange = function(){
       if (!this.readyState || this.readyState == "loaded" || this.readyState == "complete"){
         //清除JS
         doc_head.removeChild(doc_js);      
        }
      }   
      doc_head.appendChild(doc_js);
  },
  http:function(){//判断是否支持xmlHttp
    if(window.XMLHttpRequest){
      return new XMLHttpRequest();
    }
    else{
      try{
        return new ActiveXObject('Msxml2.XMLHTTP')
      }
      catch(e){
        try {
          return new ActiveXObject('Microsoft.XMLHTTP');
        } catch (e) {
          return false;
        }
      }
    }
  },
  _onStateChange:function(http,url,options){
    if(http.readyState==4){
      http.onreadystatechange=function(){};//重置事件为空
      var s=http.status;
      if(typeof(s)=='number'&&s>200&&s<300){
        if(typeof(options.success)!='function')return;
        var format=http;
        if(typeof(options.format)=='string'){//判断请求数据格式
          switch(options.format){
            case 'text':
              format=http.responseText;
              break;
            case 'json':
              try{
                format=eval('('+http.responseText+')');
              }
              catch (e) {
                if (window.console && console.error) console.error(e);
              }
              break;
            case 'xml':
              format=http.responseXML;
              break;
          }
        }
      options.success(format);//成功回调
      }
      else {//请求出问题后处理
        if (window.closed) return;
        if (typeof (options.failure) == 'function') {
          var error = {
            status: http.status,
            statusText: http.statusText
          }
          //  判断是否是网络断线或者根本就请求不到服务器
          if (http.readyState == 4 && (http.status == 0 || http.status == 12030)) {
            //  是
            error.status = -1;
          }
          options.failure(error);
        }
      }
    } 
  }
};

使用方法:

ajax调用举例:

var myAjax=new ZIP_Ajax("http://www.a.com/you.php",{
  method:"get",
  data:"key=123456&name=yuchao",
  format:"json",
  success:function(data){
    ......
  }
})
跨域请求调用举例:
var jsonp=new ZIP_Ajax("http://www.a.com/you.php",{
  method:"jsonp",
  data:{key:"123456",name:"yuchao"},
  callback:function(data){
    ......
  }
})

相关推荐:

JS组件系列--组件封装深入:使用jquery data()和html 5 data-*属性初始化组件_html/css_WEB-ITnose

Ajax跨域的完美解决方案实例分享

最全ajax跨域解决方案

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