1. 程式人生 > >深入理解AJAX系列第四篇--跨域問題

深入理解AJAX系列第四篇--跨域問題

我們先了解一下域名地址的組成:http:// www . google : 8080 / script/jquery.js

  http:// (協議號)

  www (子域名)

  google (主域名)

   8080 (埠號)

  script/jquery.js (請求的地址)

  • 當協議、子域名、主域名、埠號中任意一各不相同時,都算不同的“域”。
  • 不同的域之間相互請求資源,就叫“跨域”。
    但是我們有時候需要使用AJAX請求其他域名下的請求,但是會出現拒絕訪問的情況,這是因為基於安全的考慮,AJAX只能訪問本地的資源,而不能跨域訪問。
    處理跨域的方法1 – 代理
    這種方式是通過後臺(ASP、PHP、JAVA、ASP.NET)獲取其他域名下的內容,然後再把獲得內容返回到前端,這樣因為在同一個域名下,所以就不會出現跨域的問題。
    比如在A(www.a.com/sever.php)和B(www.b.com/sever.php)各有一個伺服器,A的後端(www.a.com/sever.php)直接訪問B的服務,然後把獲取的響應值返回給前端。也就是A的服務在後臺做了一個代理,前端只需要訪問A的伺服器也就相當與訪問了B的伺服器。
    處理跨域的方法2 – JSONP(只支援GET請求)

    這種方式的原理是動態新增一個
function jsonpCallback(result) {  
     alert(result.msg);  
 }  
var JSONP=document.createElement("script");  
JSONP.type="text/javascript";  
JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback";  
document.getElementsByTagName("head")[0].appendChild(JSONP);  

JSONP優點


不受同源策略的限制,相容性更好,在古老的瀏覽器中執行的很好,不需要XMLHttpRequest支援,請求完畢後可以通過callback返回結果。
缺點
1.不支援post請求方式,只支援get方法。
2.安全性。JOSNP是從其他域中載入程式碼執行,如果別的域存在安全性問題,則此時很可能收到惡意程式碼的攻擊。此時只能放棄JSONP呼叫
3.要確定請求是否失敗並不容易,必須使用計時器檢測指定事件內是否收到響應。
處理跨域的方法3 –修改document.domain來跨子域
比如,有一個頁面,它的地址是http://www.example.com/a.html , 在這個頁面裡面有一個iframe,它的src是
http://example.com/b.html
, 很顯然,這個頁面與它裡面的iframe框架是不同域的,所以我們是無法通過在頁面中書寫js程式碼來獲
取iframe中的東西的:這個時候,document.domain就可以派上用場了,我們只要把
http://www.example.com/a.htmlhttp://example.com/b.html這兩個頁面的document.domain都設成相同的域名就可以了。但要
注意的是,document.domain的設定是有限制的,我們只能把document.domain設定成自身或更高一級的父域,且主域必須相同。注
意:修改document.domain的方法只適用於不同子域的框架間的互動。
處理跨域的方法4 –使用HTML5的window.postMessage方法
window.postMessage(message,targetOrigin) 方法是Html5新引進的特性,可以使用它來向其它的window物件傳送訊息,無論這個
window物件是屬於同源或不同源,目前IE8+、FireFox、Chrome、Opera等瀏覽器都已經支援window.postMessage方法。
呼叫postMessage方法的window物件是指要接收訊息的那一個window物件,該方法的第一個引數message為要傳送的訊息,類 型只能為字串;第二個引數targetOrigin用來限定接收訊息的那個window物件所在的域,如果不想限定域,可以使用萬用字元 * ;
使用postMessage來跨域傳送資料還是比較直觀和方便的,但是缺點是IE6、IE7、IE8不支援,所以用不用還得根據實際需要來決定。
處理跨域的方法5 –影象Ping
影象Ping是與伺服器進行簡單、單向的跨域通訊的一種方式。請求的資料是通過查詢字串形式傳送的,而響應可以是任意內容,但通常是影象或204響應。

var img = new Image();
img.onload = img.onerror = function(){
    alert("Done");
}
img.src = "http://www.example.com/test?name=Tom";

影象ping常用於跟蹤使用者點選頁面或動態廣告曝光次數。
缺點:1.只能傳送GET請求
2.無法訪問伺服器的響應文字
處理跨域的方法6 –window.name
window物件有個name屬性,該屬性有個特徵:即在一個視窗(window)的生命週期內,視窗載入的所有的頁面都是共享一個 window.name的,每個頁面對window.name都有讀寫的許可權,window.name是持久存在一個視窗載入過的所有頁面中的,並不會因 新頁面的載入而進行重置;
比如:有一個頁面a.html,它裡面有這樣的程式碼:
這裡寫圖片描述
再看看b.html頁面的程式碼:
這裡寫圖片描述
a.html頁面載入後3秒,跳轉到了b.html頁面,結果為:
這裡寫圖片描述