搜尋
首頁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.客户端将回调函数名写入<script>脚本的url参数中。</script>

   2.script加载的时候会发送跨域请求。

4.2.服务器端

 1.通过url得到函数名,命名为callback

 2.将请求的数据作为函数的参数格式转化json格式,命名为。

 3.将返回结果拼接为 callback+"("+json+")"; --------返回的就是填充式的数据,这段数据在脚本中会自动执行。

 4.返回数据.

 4.3.JSONP技术的缺点

 1.因为是通过url传参数,所以请求只能是get类型的。

 2.<script>目前只有onload属性事件,onerror还没有统一化,如果加载脚本出错,客户端很难得到反馈。</script>

 3.所请求数据的站点必须是可信任的,如果返回的数据段中注入的有恶意的代码,危害较大,且难以发现。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

Django框架如何使用ajax的post方法

JQuery ajax 返回json时出现中文乱码该如何解决

如何解决JQuery ajaxSubmit提交中文乱码

以上是AJAX機制詳解以及跨域通信的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

使用Next.js(後端集成)構建多租戶SaaS應用程序使用Next.js(後端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

如何使用Next.js(前端集成)構建多租戶SaaS應用程序如何使用Next.js(前端集成)構建多租戶SaaS應用程序Apr 11, 2025 am 08:22 AM

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

JavaScript:探索網絡語言的多功能性JavaScript:探索網絡語言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

JavaScript的演變:當前的趨勢和未來前景JavaScript的演變:當前的趨勢和未來前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

神秘的JavaScript:它的作用以及為什麼重要神秘的JavaScript:它的作用以及為什麼重要Apr 09, 2025 am 12:07 AM

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

Python還是JavaScript更好?Python還是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。1.Python以简洁语法和丰富库生态著称,适用于数据分析和Web开发。2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

如何安裝JavaScript?如何安裝JavaScript?Apr 05, 2025 am 12:16 AM

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。