跨瀏覽器 跨域資源共享 解決方案


前言

  通過XHR實現ajax通信的一個主要限制是 跨域安全策略。XHR對象只能訪問與包含他的頁面位於同一個域的資源。當發起一個資源請求的時候,請求頭會帶有一個 Origin頭部,響應頭會帶有一個Access-Origin-Allow-Origin,如下:

Origin:http://www.test.com
Access--Control-Allow-Origin: http://www.test.com
// Access--Control-Allow-Origin: * // 代表公共資源

如果這個頭部和Origin頭部不相符合的時候,瀏覽器會駁回請求。於是就出現了跨域請求技術,下面是幾種方式的總結.

 

實現一:跨瀏覽器的CORS

 1 function createCORSRequest(method,url) {
 2   var xhr = new XMLHttpRequest();
 3   if ("withCredentials" in xhr){
 4     xhr.open(method,url,true);
 5   }else if(typeof XDomainRequest!== "undifined"){
 6     xhr=new XDomainRequest();
 7     xhr.open(method,url);
 8   }else{
 9     xhr=null;
10   }
11   return xhr;
12 }
13 
14 var request=createCORSRequest('get','http://www.test.com');
15 if(request){
16   request.onload=function(){
17     // onreadystatechange檢測成功
18     // 處理 requset.responseText
19   }
20   request.onerror=function(){
21     // 處理請求失敗
22   }
23   requset.send(null);
24 }

上面是跨瀏覽器的實現方式,下面分析一下:

IE對CORS的實現

  IE8中引入了XDR(XDomainRequest)類型,此類型和XMLHttpResquest相似,但是可以實現安全的跨域通信。

不同之處:

①  不能通過setRequestHeader()設置自定義頭部,只能設置請求頭部信息的Content-Type字段,   xhr.contentType  

②  不能訪問響應頭信息,即調用getAllResponseHeaders()總是返回空字符串

③  不能發送和接受cookie

XDR對象的方法

①  open() 只接受兩個參數,所有XDR請求都是異步的

②  send() 同XHR對象一樣

其他事件

 

 1 var xdr=new XDomainRequest();
 2 xdr.onload=function(){
 3   //  xdr.responseText 響應的原始文本
 4   // 無法確定 響應的狀態代碼,即無 xhr.readyState和xhr.status
 5 }
 6 xdr.onerror=function(){
 7   alert("An error occurred.");
 8 }
 9 xdr.open('get',"url");
10 xdr.send(null);

 

 

 

其他瀏覽器對CORS的實現

  FireFox3.5+,Safari4+,Chrome等等都實現了原生CORS的支持。但是默認情況下,跨域請求不提供憑據,可以設置withCredentials表示帶憑據的請求

 

於是,設置跨瀏覽器的CORS的時候,可以先檢測是否帶  withCredentials 屬性,若無,再檢測是否存在XDomainRequest對象。

 

實現二: 圖像Ping

  可行性:網頁可以從任何網頁中加載圖像,不用擔心跨域問題。

  具體實現:利用 img 標簽,動態創建圖像。

1 var img=new Image();
2 img.onload=img.onerror=function(){
3   alert("done");
4 }
5 img.src="http://www.example.com/test?name=Kasmine";

   這里創建了一個Image實例,通過 img.src 向服務器發起GET請求(參數為name),服務器收到請求后,通過對請求url的解析,判斷請求內容。

  應用:圖像Ping主要用於用戶點擊頁面或者瀏覽量的統計。

  缺點:只有get請求,不能訪問服務器的響應文本

實現三: JSONP

  jsonp :“JSON with padding”顧名思義就是 包含在函數回調的json數據。具體實例如下:

1 function handleResponse(response) {
2   // 處理 response
3 }
4 var script=document.createElement("script");
5 script.src='http://www.example.com?callback=handleResponse';
6 document.body.insertBefore(script,document.body.firstChild);

<script>標簽和<img>標簽一樣,不受訪問域的限制。首先我們創建一個 script 元素,插入到頁面后立刻執行。客戶端定義了一個名為handleResponse的回調函數,向 http://www.example.com 發起GET請求,服務器端進行響應:

callback({"name":"Nicholes"});

客戶端在響應到來時,會調用 回調函數 handleResponse

 

實現四:修改document.domain跨子域

  兩個域名必須屬於同一個基礎域名

實現五:通過使用HTML5的window.postMessage方法來傳送數據

始終使用origin和source屬性驗證發件人的身份

1 窗口A:
2 window.postMessage(msg,urlOfB);
3 窗口B:
4 window.onmessage(event){ 
5      var data=event.data;
6      var origin=event.origin;
7 }

 

 

 

 

小結 

  同源策略是XHR的一個約束,他要求“相同的域,相同的端口,相同的協議”才能進行通信。於是就出現了跨域訪問的技術。

實現 跨域還有其他的方法,在這里就不多說了,日后學習到了,再繼續補上~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM