AJAXの仕組みとクロスドメイン通信について詳しく解説

亚连
リリース: 2018-05-25 11:42:22
オリジナル
1530 人が閲覧しました

最近取り組んだプロジェクトで、ドメインを越えてデータを取得するために ajax が必要だったので、プロセスに少しミスがあったため、ajax を見直し、クロスドメインの問題に関する重要なポイントを記録し、全員と共有しました

。 1. Ajax

1.1. Ajax の概要
Ajax の概要 このパートでは、主に ajax の起源について説明します。なぜなら、これらはテクノロジーとは何の関係もないからです。したがって、ほとんどの詳細は一度に説明されます。

Ajaxの起源?

Ajaxという用語は、2005年にJesse James Garrettによって出版された「Ajax: A new Approach to Web Applications」というタイトルの記事に由来しています。この記事で彼は新しいテクノロジーを紹介しました。彼の言葉では、それはAjax : Asynchronous JavaScriptの略です。 +XML。

Ajax とは何ですか?

この新しいテクノロジーの主な目的は、フロントエンド Web ページがページをアンロードせずにサーバーに追加データを要求できるようにすることです。この技術の登場以来、Microsoft が率先して XHRt オブジェクト (Ajax が実装できる核となるオブジェクト) を導入し、その後他のブラウザーも次々とこの技術を実装してきました。つまり、ajax は非同期通信を可能にするテクノロジーです。

1.2. Ajax のコア オブジェクト---XMLHttpRequest
この XHR オブジェクトは IE5 が最初に導入したため、当時は事実上の標準はありませんでした。 IE には 3 つの異なる XHR オブジェクト バージョンがあります: MSXML2。このオブジェクトの導入後、他のブラウザ メーカーも追随し、現在では XHR オブジェクトが事実上の標準になりました。ブラウザ間で XHR オブジェクトを作成します。

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;
}
ログイン後にコピー

1.2.xmlhttpRequest の使用法

XMLHTTPREQUEST には 6 つの関数があります:

Rreeee

XMLHTTPRequest 属性: ResponseText は応答テーマとして記述されます。 応答が text/html または application の場合は、テキスト

responseXML を返します。 /xml タイプ、この属性は応答 XML ドキュメントを保存します

status http 応答ステータス コード
statusText http ステータスの説明

readyState XMLHttpRequest オブジェクトのステータス ビット 0 1 2 3 4 はそれぞれ 5 つの状態を表します

timeout タイムアウト時間、単位を設定します現在、IE8+ のみがサポートしています---まだ標準化されていません (推奨されていません)

XMLHttpRequest オブジェクトのイベント属性 onReadyStateChange:-----すべてのブラウザと互換性があります

この属性は、 XMLHttpRequest オブジェクト:

ReadyState の変更は次の状態に対応します:

0: まだ初期化されていません。 open() が呼び出される前

1: 開始します。 open() を呼び出した後、send() が呼び出されません;

2: 送信します。 send() を呼び出しましたが、まだ応答がありません。

3: データを受信して​​います。レスポンスデータを受信して​​から受信完了まで。

4: 完了。データの受信が完了しました。

function createXHttpRequest() {
  if (typeof XMLHttpRequest !== 'undefined') { //不要用 if(XMLHttpRequest){}这种形式,
    return new XMLHttpRequest();              //如果是这种形式在找不到XMLHttpRequest函数的情况下,会报错。
} else if (typeof ActiveXObject !== 'undefined') { 
         return createXHR(); //用到刚才我们创建的函数 
  } else { throw new Error('不能创建XMLHttpRequest对象'); } }
ログイン後にコピー
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 请求。
ログイン後にコピー

この使用方法では注意が必要な問題があります。つまり、データの処理時に xhr.status 属性にアクセスすると、タイムアウト後も onreadystatechange イベントがトリガーされます。 onreadychange イベントの場合、エラーが発生します。したがって、このプロパティにアクセスするときに try catch 処理を行う必要があります。{}ただし、この属性は当面互換性がないため、焦点を当てません。 PXmlhttpRequest オブジェクト イベント プロパティ ONLOAD One Onbort Onbort Onprogress:

----- 非 IE ブラウザおよび IE 10 以降では、イベントは便宜的に実装されています。

2 つのイベント onload と onprogress はそれぞれ、readyState=4 とreadyState=3 に対応します。使用方法は次のとおりです。

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

追加: 一部のイベントは、readyState のステータスに基づいてシミュレートできます。これを簡単にできるのは一部のブラウザだけです。

3. 一方向クロスドメイン技術 --- CORS

今日お話しするのは、クライアントの Web ページが返されたデータを受信するときに、同じドメインにないサーバーからデータを要求するということです。 、コールバック関数を使用してデータを処理します。

つまり:

1. クライアントはドメイン外のサーバーにデータを要求します

2. サーバーは応答を取得した後、クライアントにデータを送信します。

3. クライアントは、返されたデータに基づいてコールバック関数を実行します。

我知道不同域下的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);
ログイン後にコピー

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);
}
ログイン後にコピー

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>
ログイン後にコピー

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

人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!