首頁 web前端 js教程 AJAX機制詳解以及跨域通信

AJAX機制詳解以及跨域通信

May 25, 2018 am 11:42 AM
ajax 溝通

最近做的一個專案中需要ajax跨域取得數據,中間出了點小差錯,於是把ajax複習一下,記錄下來關於跨域的問題的要點,分享給大家

1.Ajax

1.1.Ajax簡介
  Ajax簡介這一部分我們主要是談一下ajax的起源,ajax是什麼?因為這些都是跟技術無關的。所以,大多細節都是一筆帶過。

  Ajax的起源?

  Ajax一詞源自於2005年Jesse James Garrett發表的一篇題為"Ajax:A new Approach to Web Applications".他在這篇文       章中介紹了一種新技術,並用他的話說,就是Ajax :Asynchronous JavaScript XML的縮寫。

  Ajax是什麼?

  這種新技術的主要目的就是為了讓前端網頁能夠向伺服器請求額外的資料而不需要卸載頁面。自從這種技術出現以後,微軟率先引進XHRt物件(ajax能夠實現的核心物件),然後其他瀏覽器相繼實作此技術。總而言之,ajax就是一種能非同步通訊的技術。

1.2.Ajax的核心物件---XMLHttpRequest
#  因為IE5是最早引入這個XHR物件的,當時並沒有事實上的標準。在IE中有三種不同的XHR物件版本:MSXML2.XMLHttp,MSXML2.XMLHttp.3.0和MSXML2.XMLHttp.6.0;

#根據這三種版本號,在IE中建立一個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;
}
登入後複製

在IE引進這個物件之後,其他瀏覽器廠商也相繼跟隨,這時候XHR物件成為事實上的標準!

跨瀏覽器建立XHR物件;

function createXHttpRequest() {
  if (typeof XMLHttpRequest !== 'undefined') { //不要用 if(XMLHttpRequest){}这种形式,
    return new XMLHttpRequest();              //如果是这种形式在找不到XMLHttpRequest函数的情况下,会报错。
} else if (typeof ActiveXObject !== 'undefined') { 
         return createXHR(); //用到刚才我们创建的函数 
  } else { throw new Error('不能创建XMLHttpRequest对象'); } }
登入後複製

1.2.XMLHttpRequest的用法
XMLHttpRequest物件的函數有6個:

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 请求。
登入後複製

  XMLHttpRequest物件的屬性有5個:

屬性 描述
responseText 作為回應主體被傳回的文字
responseXML 如果相回應的是text/html或是application/xml類型的話,這個屬性將會保存著回應的XML文件
status http的回應狀態碼
statusText http狀態的說明
readyState XMLHttpRequest物件的狀態位元0 1 2 3 4 分別表示5種狀態
timeout 設定逾時時間,單位是ms.目前只有IE8 支援---尚未標準化(不建議使用)

  XMLHttpRequest物件的事件屬性onReadyStateChange:-----所有瀏覽器相容

#  此屬性監聽的是  XMLHttpRequest物件的readyState屬性的變更:

  readyState的變更分別對應如下狀態:

  0:尚未初始化。未呼叫open()之前

  1:啟動。呼叫open()之後,但是未呼叫send();

  2:傳送。呼叫send()但是尚未得到回應。

  3:正在接收資料。剛接收到回應資料開始到接收完成之前。

  4: 完成。資料接收完成。

xhr.onreadystatechange = function () {
 if (xhr.readyState == 4) {
  if (xhr.status >= 200 && xhr.status <== 300 || xhr.status == 304) {
   alert(xhr.responseText);
   //处理接收的数据
  } else {
   //请求失败,未得到响应数据
  }
 }
}; //补充说明:注册事件必须发生在send()以前
登入後複製
XMLHttpRequest对象的事件属性ontimeout -----仅限IE8+,不过最新的主流高版本浏览器也已经实现(不推荐使用)
xhr.timeout=1000;//一秒钟
xhr.ontimeout=functon(){  //处理代码  ......}
登入後複製

  這種使用方式有個問題需要注意,就是在逾時之後,在接收到資料後仍然會觸發onreadystatechange事件,如果在處理onreadychange事件時存取xhr.status屬性,會出錯。所以我們在存取該屬性時需要做一下try{}catch處理。但是,因為這個屬性暫不相容,所有我們就不重點講了。

XMLHttpRequest對象的事件屬性onload onerror onloadstar onbort onprogress:

                                                                                                   -----非IE瀏覽器和IE 10 已實現

       onload在IE8以上可以實現,大部分事件根據readySate變化均可實現,以上事件只不過是方便使用而已。

  onload和onprogress 這兩個事件分別對應著readyState=4和readyState=3的情況,使用方式分別如下:

   xhr.onload= function (event) {
      //event只包含一个属性 event.target=xhr;使用方式只是在readyState=4时差不多..
    }
   xhr.onprogress=function(event){
     //event除了包含event.target=xhr之外,还包含三种属性
     //lengthComputale(进度信息是否可用),position(已接受字节数)和totalSize(总字节数).
     
   }
登入後複製


補充:有些事件都可以根據readyState的狀態進行模擬。只有有的瀏覽器進行了方便化處理而已。

3.單向跨域技術---CORS
 今天我們這裡講的是客戶端網頁向不在同一個域的伺服器請求資料..客戶端在收到傳回的資料時,用回呼函數處理資料。

即:

 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.客户端将回调函数名写入

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

新一代光纖寬頻技術 ——50G PON 新一代光纖寬頻技術 ——50G PON Apr 20, 2024 pm 09:22 PM

上篇文章(連結),小棗君向大家介紹了寬頻技術從ISDN、xDSL到10GPON的發展歷程。今天,我們來聊聊即將到來的新一代光纖寬頻技術—50GPON。 █F5G和F5G-A介紹50GPON之前,先來談談F5G和F5G-A。 2020年2月,ETSI(歐洲電信標準化協會)推進了一套以10GPON+FTTR、Wi-Fi6、200G光傳送/匯聚、OXC等技術為基礎的固定通訊網路技術體系,並將其命名為F5G,也就是第五代固網通訊技術(The5thgenerationFixednetworks)。 F5G是固網

解決jQuery AJAX請求遇到403錯誤的方法 解決jQuery AJAX請求遇到403錯誤的方法 Feb 20, 2024 am 10:07 AM

標題:解決jQueryAJAX請求出現403錯誤的方法及程式碼範例403錯誤是指伺服器禁止存取資源的請求,通常會導致出現這個錯誤的原因是請求缺少權限或被伺服器拒絕。在進行jQueryAJAX請求時,有時會遇到這種情況,本文將介紹如何解決這個問題,並提供程式碼範例。解決方法:檢查權限:首先要確保請求的URL位址是正確的,同時驗證是否有足夠的權限來存取該資

PHP 與 Ajax:建立一個自動完成建議引擎 PHP 與 Ajax:建立一個自動完成建議引擎 Jun 02, 2024 pm 08:39 PM

使用PHP和Ajax建置自動完成建議引擎:伺服器端腳本:處理Ajax請求並傳回建議(autocomplete.php)。客戶端腳本:發送Ajax請求並顯示建議(autocomplete.js)。實戰案例:在HTML頁面中包含腳本並指定search-input元素識別碼。

解決jQuery AJAX請求403錯誤的方法 解決jQuery AJAX請求403錯誤的方法 Feb 19, 2024 pm 05:55 PM

jQuery是一個受歡迎的JavaScript函式庫,用來簡化客戶端端的開發。而AJAX則是在不重新載入整個網頁的情況下,透過發送非同步請求和與伺服器互動的技術。然而在使用jQuery進行AJAX請求時,有時會遇到403錯誤。 403錯誤通常是伺服器禁止存取的錯誤,可能是由於安全性原則或權限問題導致的。在本文中,我們將討論如何解決jQueryAJAX請求遭遇403錯誤

如何解決jQuery AJAX報錯403的問題? 如何解決jQuery AJAX報錯403的問題? Feb 23, 2024 pm 04:27 PM

如何解決jQueryAJAX報錯403的問題?在開發網頁應用程式時,經常會使用jQuery來發送非同步請求。然而,有時在使用jQueryAJAX時可能會遇到錯誤代碼403,表示伺服器禁止存取。這種情況通常是由伺服器端的安全性設定所導致的,但可以透過一些方法來解決這個問題。本文將介紹如何解決jQueryAJAX報錯403的問題,並提供具體的程式碼範例。一、使

寬頻上網技術簡史 寬頻上網技術簡史 Apr 16, 2024 am 09:00 AM

在現今這個數位時代,寬頻已經成為我們每個人、每個家庭的生活必需品。如果沒有它,我們會坐立難安、心緒不寧。那麼,你知道寬頻背後的技術原理嗎?從最早期的56k「貓」撥號,到現在的千兆城市、千兆家庭,我們的寬頻科技到底經歷了怎樣的改變?今天這篇文章,我們就來詳細了解一下—「寬頻的故事」。 █xDSL和ISDN下面這個介面,你看過嗎?我相信很多70後80後的小夥伴,肯定見過,非常熟悉。沒錯,這就是當年我們最初接觸網路時,進行「撥接上網」的介面。那還是20多年前,小棗君還在上大學的時候。為了上網,我

無線滑鼠的發展史 無線滑鼠的發展史 Jun 12, 2024 pm 08:52 PM

原文標題:《無線滑鼠到底是怎麼做到無線的? 》無線滑鼠慢慢成了現在辦公電腦的標配,從此再也不用拖著長長的線跑來跑去了。可是,無線滑鼠是怎麼運作的呢?今天我們一起來學習No.1無線滑鼠的發展史你知道嗎,無線滑鼠現在也已經40歲了,1984年的時​​候,羅技研製了世界上第一款無線滑鼠,不過這個無線滑鼠採用紅外線作為訊號的載體,據說長得像下面圖片這個樣子,後面因為效能原因而宣告失敗。直到十年後的1994年,羅技終於研發成功了一個工作在27MHz的無線滑鼠,這個27MHz頻率也成了很長一段時間內,無線滑鼠

PHP實作Socket通訊的方法與技巧 PHP實作Socket通訊的方法與技巧 Mar 07, 2024 pm 02:06 PM

PHP是一種常用的開發語言,可以用來開發各種網頁應用程式。除了常見的HTTP請求和回應以外,PHP也支援透過Socket進行網路通信,實現更靈活和高效的資料互動。本文將介紹PHP如何實作Socket通訊的方法與技巧,並附上具體的程式碼範例。什麼是Socket通訊Socket是一種在網路中進行通訊的方法,可以在不同的電腦之間傳輸資料。透過S

See all articles