Heim > Web-Frontend > js-Tutorial > Hauptteil

Detaillierte Erläuterung des AJAX-Mechanismus und der domänenübergreifenden Kommunikation

亚连
Freigeben: 2018-05-25 11:42:22
Original
1530 Leute haben es durchsucht

In einem Projekt, an dem ich kürzlich gearbeitet habe, brauchte ich Ajax, um domänenübergreifende Daten zu erhalten, aber etwas ging schief. Also habe ich Ajax überprüft, die wichtigsten Punkte zu domänenübergreifenden Problemen aufgezeichnet und sie mit allen geteilt

1.Ajax

1.1. Einführung in Ajax
Einführung in Ajax In diesem Teil sprechen wir hauptsächlich über den Ursprung von Ajax. Denn diese haben nichts mit Technik zu tun. Daher werden die meisten Details auf einen Schlag erwähnt.

Der Ursprung von Ajax?

Der Begriff Ajax stammt aus einem Artikel mit dem Titel „Ajax: Ein neuer Ansatz für Webanwendungen“, der 2005 von Jesse James Garrett veröffentlicht wurde. In diesem Artikel stellte er eine neue Technologie vor, in seinen Worten heißt es: Ajax : die Abkürzung für Asynchronous JavaScript +XML.

Was ist Ajax?

Der Hauptzweck dieser neuen Technologie besteht darin, der Front-End-Webseite die Anforderung zusätzlicher Daten vom Server zu ermöglichen, ohne die Seite zu entladen. Seit dem Aufkommen dieser Technologie hat Microsoft die Führung bei der Einführung des XHRt-Objekts übernommen (das Kernobjekt, das Ajax implementieren kann), und dann haben andere Browser diese Technologie nacheinander implementiert. Alles in allem handelt es sich bei Ajax um eine Technologie, die asynchrone Kommunikation ermöglicht.

1.2. Das Kernobjekt von Ajax---XMLHttpRequest
Da IE5 der erste war, der dieses XHR-Objekt einführte, gab es zu diesem Zeitpunkt keinen De-facto-Standard. Es gibt drei verschiedene Versionen von XHR-Objekten im IE: 🎜>

function createXHR() { //IE7之前的版本通过这种方式
  var versions = [
    'MSXML2.XMLHttp',
    'MSXML2.XMLHttp.3.0',
    'MSXML2.XMLHttp.6.0'
  ];
  var xhr = null;
  for (var item in versions) {
    try {
      xhr = new ActiveXObject(item); //若不存在该版本,可能会出错
      if (xhr) break;
    } catch (e) {
      //一般对这种错误不做处理
    }
  }
  return xhr;
}
Nach dem Login kopieren

Nachdem der IE dieses Objekt eingeführt hatte, folgten auch andere Browser-Hersteller diesem Beispiel. Zu diesem Zeitpunkt wurde das XHR-Objekt zum De-facto-Standard!

XHR-Objekte browserübergreifend erstellen; Es gibt 5 Attribute des Objekts:

AttributbeschreibungresponseText Der als Antwortthema zurückgegebene TextresponseXML Wenn die Antwort ist text/html oder application/xml Typ, dieses Attribut wird gespeichert. Das Antwort-XML-Dokument

Status http-Antwortstatuscode

statusText HTTP-Statusbeschreibung
readyState Die Statusbits des XMLHttpRequest-Objekts 0 1 2 3 4 bzw stellt 5 Zustände dar

timeout Stellen Sie die Timeout-Zeit ein, die Einheit ist derzeit nur von IE8+ unterstützt --- noch nicht standardisiert (nicht empfohlen)

Das Ereignisattribut onReadyStateChange des XMLHttpRequest-Objekts: --- --kompatibel mit allen Browsern


Dieses Attribut hört auf XMLHttpRequest Änderungen im readyState-Attribut des Objekts:

Änderungen im readyState entsprechen den folgenden Zuständen:

0: Nicht noch initialisiert. Bevor open() aufgerufen wird

1: Start. Nach dem Aufruf von open() wird send() jedoch nicht aufgerufen

2: Send. Send() aufgerufen, aber noch keine Antwort erhalten.

3: Daten empfangen. Vom Zeitpunkt des Empfangs der Antwortdaten bis zum Abschluss des Empfangs.

4: Abgeschlossen. Datenempfang abgeschlossen.

function createXHttpRequest() {
  if (typeof XMLHttpRequest !== 'undefined') { //不要用 if(XMLHttpRequest){}这种形式,
    return new XMLHttpRequest();              //如果是这种形式在找不到XMLHttpRequest函数的情况下,会报错。
} else if (typeof ActiveXObject !== 'undefined') { 
         return createXHR(); //用到刚才我们创建的函数 
  } else { throw new Error('不能创建XMLHttpRequest对象'); } }
Nach dem Login kopieren
open("method",url,boolean);
              //该方法的三个参数,分别为----提交方式"get"或者"post"等 
                //&& url是相对于执行代码的当前页面的路径(使用绝对路径是允许的)&&是否异步 
send();    
           //这个方法接收一个参数,这个参数是作为请求主体发送的数据, 
           //说明: 如果有参数,请使用post方式提交 使用方式如下,send("user="+username+"&pwd="+password);
           //如果没有参数,为了兼容性考虑,必须在参数中传入null,即send(null);该方式使用get方式提交

abort();       //取消当前响应,关闭连接并且结束任何未决的网络活动。

          //这个方法把 XMLHttpRequest 对象重置为 readyState 为 0 的状态,并且取消所有未决             //的网络活动。例如,如果请求用了太长时间,而且响应不再必要的时候,可以调用这个方法。

getResponseHeader()   

          //返回指定的 HTTP 响应头部的值。其参数是要返回的 HTTP 响应头部的名称。可以使用任             //何大小写来制定这个头部名字,和响应头部的比较是不区分大小写的。

          //该方法的返回值是指定的 HTTP 响应头部的值,如果没有接收到这个头部或者 readyStat             //e 小于 3 则为空字符串。如果接收到多个有指定名称的头部,这个头部的值被连接起来并             //返回,使用逗号和空格分隔开各个头部的值。

getAllResponseHeaders()       

          //把 HTTP 响应头部作为未解析的字符串返回。

          //如果 readyState 小于 3,这个方法返回 null。否则,它返回服务器发送的所有 HTTP 响应的

          //头部。头部作为单个的字符串返回,一行一个头部。每行用换行符 "\r\n" 隔开。

setRequestHeader()

         //向一个打开但未发送的请求设置或添加一个 HTTP 请求。
Nach dem Login kopieren

Bei dieser Art der Verwendung gibt es ein Problem, das beachtet werden muss, d. h. nach dem Timeout wird das onreadystatechange-Ereignis nach dem Empfang der Daten immer noch ausgelöst Wenn bei der Verarbeitung des onreadychange-Ereignisses auf den Zugriff zugegriffen wird, tritt ein Fehler auf. Daher müssen wir beim Zugriff auf diese Eigenschaft eine try{}catch-Verarbeitung durchführen. Da dieses Attribut jedoch vorerst nicht kompatibel ist, werden wir uns nicht darauf konzentrieren.

Ereignisattribut onload onerror onloadstar onprogress of XMLHttpRequest object:

                -----Nicht-IE-Browser und IE 10+ wurden implementiert

onload kann in IE8 implementiert werden oder höher, die meisten Ereignisse können gemäß readySate-Änderungen realisiert werden. Die oben genannten Ereignisse dienen nur der Bequemlichkeit.

Die beiden Ereignisse onload und onprogress entsprechen readyState=4 bzw. readyState=3. Die Verwendungsmethoden lauten wie folgt:

xhr.onreadystatechange = function () {
 if (xhr.readyState == 4) {
  if (xhr.status >= 200 && xhr.status <== 300 || xhr.status == 304) {
   alert(xhr.responseText);
   //处理接收的数据
  } else {
   //请求失败,未得到响应数据
  }
 }
}; //补充说明:注册事件必须发生在send()以前
Nach dem Login kopieren

Zusätzlich: Einige Ereignisse können auf readyState basieren. Status wird simuliert. Nur einige Browser haben es einfacher gemacht.

3. Einweg-Domänenübergreifende Technologie---CORS

Worüber wir heute sprechen, ist, dass die Client-Webseite Daten von einem Server anfordert, der sich nicht in der befindet Dieselbe Domäne. Der Client empfängt. Wenn die zurückgegebenen Daten empfangen werden, verwenden Sie die Rückruffunktion, um die Daten zu verarbeiten.

Das heißt:


1. Der Client fordert Daten vom Server außerhalb der Domäne an

2. Der Server sendet Daten an den Client, nachdem er die Antwort erhalten hat. 3. Der Client führt die Rückruffunktion basierend auf den zurückgegebenen Daten aus.

我知道不同域下的iframe也可以进行通信,而且这也是一种跨域通信技术。但是,这种iframe页面之间的双向通信,我们在下一个专题里面讲解,今天主要讲的是单向通信。

3.1.CORS跨域请求的原理
在用xhr(XMLHttpRequest)对象或者xdr(XDomainRequest)对象,发送域外请求时,大概的实现原理如下图:

3.2.IE中CORS技术的实现
IE8引入了一个XDR类型,这个类型与XHR基本类似,但是其能实现安全可靠地跨域通信。

XHD的特点:

1.cookie不会随请求发送,也不会随响应返回。

2.只能设置请求头部中的Content-Type片段。

3.不能访问响应头部信息。

4.只是支持get和post请求。

XDR支持onload和onerror事件属性,且其使用方式和XHR基本一致,不过其open()只接收两个参数,默认是异步的。

var xdr = new XDomainRequest();
xdr.onload = function () {
 //处理xdr.responseText
}
xdr.onerror = function () {
};
xdr.open(&#39;get&#39;, &#39;绝对url&#39;);
xhr.send(null);
Nach dem Login kopieren

3.3.跨浏览器的CORS技术实现

在标准浏览器中XHR对象就已经可以自动实现跨域请求,但是XHR和XDR的不同之处:

1.XHR可以在设置 withCredentials =true时,浏览器会把cookie发送给服务器,服务器此时通过设置头部Access-Control-Allow-Credentials:true时来响应。如果,服务器不设置这个属性,则浏览器会触发onerror事件。

2.在回调函数中可以访问status和statusText属性,而且支持同步请求。

以下是实现跨域请求的代码:

function createCrosRequest(method, url) {
 var xhr = new XMLHttpRequest(); //IE7+
 if (&#39;withCredentials&#39; in xhr) { //IE8-IE9浏览器没有这个属性
  xhr.open(method, url, true);
 } else if (typeof XDomainRequest != &#39;undefined&#39;) {
  xhr = new XDomainRequest();  //IE
  xhr.open(method, url)
 }
 return xhr;
}
var request=CreateCrosRequest("get","url");
if(request){
 request.onload=function(){
 //处理request.responseText;
 }
 request.send(null);
}
Nach dem Login kopieren

4.单向跨域技术 ---JSONP技术

JSONP技术比较简单,其主要原理主要是利用script标签的特性。

script标签和image标签一样,它们都具有src属性,而且这个属性是可跨域的。

因为script标签返回的都是js代码,且该js代码会自动执行。所以,如果我们请求返回的数据也是类似一段js代码的形式,岂不是就可以实现在脚本加载完毕后自动执行。

如果我们的请求,返回的数据是 callback + '(' + json + ')'; 这种形式的数据, 那么在脚本加载完毕之后也就能自动执行callback()函数了.

4.1.客户端写法

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body>
    <button id="button">请求数据</button>
</body>
<script>
  window.onload=function(){
    var button=document.getElementById("ibutton");
    function callback(data){
      //处理data
    }
    button.onclick=function(){
      var script=document.createElement("script");
      script="http://www.sasd.com/json/?callbak=callback"; 
      document.body.insertBefore(script,document.body.firstChild);//加载脚本
      
    }
    
  }
</script>
</html>
Nach dem Login kopieren

   1.客户端将回调函数名写入

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!