Heim  >  Artikel  >  Web-Frontend  >  Ausführliche Erläuterung der benutzerdefinierten Ajax-Unterstützung für die domänenübergreifende Komponentenkapselung

Ausführliche Erläuterung der benutzerdefinierten Ajax-Unterstützung für die domänenübergreifende Komponentenkapselung

小云云
小云云Original
2018-02-09 09:49:28970Durchsuche

Dieser Artikel enthält hauptsächlich eine detaillierte Analyse der Wissenspunkte im Zusammenhang mit der benutzerdefinierten Ajax-Unterstützung für die domänenübergreifende Komponentenkapselung. Freunde, die daran interessiert sind, können darauf verweisen und hoffen, allen zu helfen.

Class.create()-Analyse

Prototyp imitieren, um Klassenvererbung zu erstellen

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;
};

Ajax-Definition: ZIP_Ajax=Class.create();

Die Methode create gibt eine Konstruktoranforderung zurück, die var ZIP_Ajax= function(){ this.request.apply(this, arguments }); entspricht, indem sie vorgibt, ein Objekt zu sein Das Ausführen eines Konstruktionsprozesses entspricht der Übergabe der Konstruktoraufgabe an die Anforderungsmethode. Dies ist die Methode der ZIP_Ajax-Instanz, und diese verweist schließlich auf die ZIP_Ajax-Instanz , dies verweist tatsächlich auf die ZIP_Ajax-Klasse. Mit der Definition der Klasse ZIP_Ajax können Sie dann deren Methode definieren:

Detaillierte Erklärung von XMLHttpRequest:

XMLHttpRequest ist keine Technologie, sondern eine in Mainstream-Browser integrierte Funktion zu HTTP-Protokollobjekten. Die meisten herkömmlichen HTTP-Anfragen basieren auf der Übermittlung eines Formulars, der HTTP-Anfrage und der anschließenden Rückgabe eines Formulars. Während XMLHttpRequest synchrone Anforderungen unterstützt, besteht der größte Vorteil darin, dass es die asynchrone Übertragung zum Empfangen von Daten unterstützt. Beim Erstellen einer neuen Ajax-Anforderung wird tatsächlich ein XMLHttpRequest-Objekt instanziiert. Stellen Sie kurz die wichtigsten Ereignisse und Methoden vor:

readystatechange-Ereignis:

Wenn XMLHttpRequest eine http-Anfrage sendet, wird ein readystatechange-Ereignis ausgelöst. Das Ereignis gibt 0 zurück , 1 und 2 repräsentieren die Erstellung von XMLHttpRequest, den Abschluss der XMLHttpRequest-Initialisierung und das Senden der Anfrage. 3 bedeutet, dass die Antwort nicht beendet wurde (d. h. nur die Antwort-Header-Daten werden empfangen). vollständige Antwort.

Der zurückgegebene Status gibt den vom Server zurückgegebenen Statuscode an:

Die am häufigsten verwendeten sind 200, die eine erfolgreiche Datenrückgabe anzeigen, 301 permanente Umleitung und 302 temporäre Umleitung (nicht Sicherheit) 304 liest zwischengespeicherte Daten, 400 zeigt einen Syntaxfehler in der Anfrage an, 403 zeigt an, dass der Server die Anfrage ablehnt, 404 zeigt an, dass die angeforderte Webseitenressource nicht existiert, 405 kann den Server am angegebenen Standort nicht finden, 408 zeigt an, dass die Anforderung abgelaufen ist, 500 zeigt einen internen Serverfehler an und 505 zeigt an, dass der Server die angeforderte http-Protokollversion nicht unterstützt.

200–300 bedeutet Erfolg, 300–400 bedeutet Umleitung, 400–500 bedeutet, dass der Inhalt oder das Format der Anfrage oder der Anfragetext zu groß ist, was zu einem Fehler führt, 500+ bedeutet interner Serverfehler

open-Methode:

open empfängt drei Parameter: Anforderungstyp (Get, Post, Head usw.), URL, synchron oder asynchron

Sendemethode:

Wenn die Anfrage bereit ist, wird die Sendemethode ausgelöst und der gesendete Inhalt sind die angeforderten Daten (wenn es sich um eine Get-Anfrage handelt, ist der Parameter null;

Nachdem die Anfrage erfolgreich war, wird eine benutzerdefinierte Methode ausgeführt, deren Parameter Rückgabedaten sind.

Ajax-Cross-Domain:

Was ist Cross? -Domain?

Wenn zwei Websites www.a.com Daten von www.b.com anfordern möchten, treten aufgrund inkonsistenter Domainnamen Probleme auf Wenn die Ports unterschiedlich sind, treten domänenübergreifende Probleme auf (aus diesem Grund kann js nur warten und beobachten.) Die Bestimmung, ob es sich um domänenübergreifende Ports handelt, wird nur durch window.location.protocol+window.location bestimmt .host. Zum Beispiel http://www.baidu.com.

Es gibt mehrere Möglichkeiten, domänenübergreifende Probleme mit js zu lösen

1 .document.domain+iframe

Für Anfragen mit derselben Hauptdomain, aber unterschiedlichen Subdomains können Domainname + Iframe als Lösung verwendet werden. Die konkrete Idee ist, dass es unter dem Domainnamen zwei verschiedene AB-Dateien gibt www.a.com/a.html

und hi.a.com/b.html, wir können document.domain=" zu den beiden HTML-Dateien a.com hinzufügen und dann erstellen ein iframe in der a-Datei, um das Inhaltsdokument des iframes zu steuern, damit die beiden Dateien kommunizieren können. Zum Beispiel:

a auf www.a.com 🎜>

In der b.html-Datei auf hi.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文件中元素
  }


document.domain="a.com";


Probleme:

1. Sicherheit: Wenn eine Seite (hi.a.com) angegriffen wird, entsteht eine Sicherheitslücke Um alle Iframes bedienen zu können, müssen Sie die gleiche Domäne festlegen


2. Skripte dynamisch erstellen (die legendäre JSONP-Methode)

Browser verbieten standardmäßig den Domänenzugriff, aber Es ist nicht verboten, auf der Seite auf JS-Dateien anderer Domänennamen zu verweisen, und in JS-Dateien eingeführte Methoden können ausgeführt werden. Auf dieser Grundlage können wir durch die Erstellung von Skriptknotenmethoden eine vollständige domänenübergreifende Kommunikation erreichen. Die Implementierungsschritte sind:


a. Laden Sie ein Skript dynamisch auf die Seite des Anforderungsinitiators. Die URL des Skripts zeigt auf das Backend des Empfängers und wird vom Initiator ausgeführt . Die URL kann Parameter übergeben und unterstützt nur das Abrufen von Übermittlungsparametern.


b. Rufen Sie beim Laden des Skripts die domänenübergreifende js-Methode für die Rückrufverarbeitung (jsonp) auf.


Zum Beispiel:


Initiator

Empfänger:
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})
}


Der Empfänger muss nur eine Ausführung zurückgeben Funktion, die Ausführungsfunktion ist der Rückruf in der Anfrage und weist Parameter zu.


3. Verwenden Sie html5 postMessage:


Eine der neuen Funktionen von HTML5 ist die dokumentübergreifende Nachrichtenübertragung, die jetzt von den meisten Browsern (einschließlich ie8+) unterstützt und verwendet wird ), das webbasiertes Echtzeit-Messaging unterstützt und keine domänenübergreifenden Probleme aufweist. postMessage wird im Allgemeinen mit iframe verwendet.

举例如下:

父页面:

<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跨域解决方案

Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung der benutzerdefinierten Ajax-Unterstützung für die domänenübergreifende Komponentenkapselung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn