JavaScript是一種在Web開發中經常使用的前端動態腳本技術。在JavaScript中,有一個很重要的安全性限制,被稱為“Same-Origin Policy”(同源策略)。這一策略對于JavaScript代碼能夠訪問的頁面內容做了很重要的限制,即JavaScript只能訪問與包含它的文檔在同一域下的內容。
JavaScript這個安全策略在進行多iframe或多窗口編程、以及Ajax編程時顯得尤為重要。根據這個策略,在baidu.com下的頁面中包含的JavaScript代碼,不能訪問在google.com域名下的頁面內容;甚至不同的子域名之間的頁面也不能通過JavaScript代碼互相訪問。對于Ajax的影響在于,通過XMLHttpRequest實現的Ajax請求,不能向不同的域提交請求,例如,在abc.example.com下的頁面,不能向def.example.com提交Ajax請求,等等。
然而,當進行一些比較深入的前端編程的時候,不可避免地需要進行跨域操作,這時候“同源策略”就顯得過于苛刻。本文就這個問題,概括了跨域所需要的一些技術。
下面我們分兩種情況討論跨域技術:首先討論不同子域的跨域技術,然后討論完全不同域的跨域技術。
(一)不同子域的跨域技術。
我們分兩個問題來分別討論:第一個問題是如何跨不同子域進行JavaScript調用;第二個問題是如何向不同子域提交Ajax請求。
先來解決第一個問題,假設example.com域下有兩個不同子域:abc.example.com和def.example.com?,F在假設在def.example.com下面有一個頁面,里面定義了一個JavaScript函數:
我們想在abc.example.com下的某個頁面里調用上面的函數。再假設我們要討論的abc.example.com下面的這個頁面是以iframe形式嵌入在def.example.com下面那個頁面里的,這樣我們可能試圖在iframe里做如下調用:
好,我們注意到,這個調用是被前面講到的“同源策略”所禁止的,JavaScript引擎會直接拋出一個異常。
為了實現上述調用,我們可以通過修改兩個頁面的domain屬性的方法做到。例如,我們可以將上面在abc.example.com和def.example.com下的兩個頁面的頂端都加上如下的JavaScript代碼片段:
這樣,兩個頁面就變為同域了,前面的調用也可以正常執行了。
這里需要注意的一點是,一個頁面的document.domain屬性只能設置成一個更頂級的域名(除了一級域名),但不能設置成比當前域名更深層的子域名。例如,abc.example.com的頁面只能將它的domain設置成example.com,不能設置成sub.abc.example.com,當然也不能設置成一級域名com。
上面的例子討論的是兩個頁面屬于iframe嵌套關系的情況,當兩個頁面是打開與被打開的關系時,原理也完全一樣。
下面我們來解決第二個問題:如何向不同子域提交Ajax請求。
通常情況下,我們會用與下面類似的代碼來創建一個XMLHttpRequest對象:
上面的代碼中引用ActiveXObject,是為了兼容IE6系列瀏覽器。每次我們調用newRequest函數,就獲得了一個剛剛創建的Ajax對象,然后用這個Ajax對象來發送HTTP請求。例如,下面的代碼向abc.example.com發送了一個GET請求:
假設上面的代碼包含在一個abc.example.com域名下的頁面里,則這個GET請求可以正常發送成功,沒有任何問題。然而,如果現在要向def.example.com發送請求,則出現跨域問題,JavaScript引擎拋出異常。
解決的辦法是,在def.example.com域下放置一個跨域文件,假設叫crossdomain.html;然后將前面的newRequest函數的定義移到這個跨域文件中;最后像之前修改document.domain值的做法一樣,在crossdomain.html文件和abc.example.com域下調用Ajax的頁面頂端,都加上:
[code]
<iframe name="xd_iframe" style="display:none" src=">
這時abc.example.com域下的頁面和跨域文件crossdomain.html都在同一個域(example.com)下,我們可以在abc.example.com域下的頁面中去調用crossdomain.html中的newRequest函數:
這樣獲得的request對象,就可以向http://def.example.com發送HTTP請求了。
(二)完全不同域的跨域技術。
如果頂級域名都不相同,例如example1.com和example2.com之間想通過JavaScript在前端通信,則所需要的技術更復雜些。
在講解不同域的跨域技術之前,我們首先明確一點,下面要講的技術也同樣適用于前面跨不同子域的情況,因為跨不同子域只是跨域問題的一個特例。當然,在恰當的情況下使用恰當的技術,能夠保證更優的效率和更高的穩定性。
簡言之,根據不同的跨域需求,跨域技術可以歸為下面幾類:
1、JSONP跨域GET請求
2、通過iframe實現跨域
3、flash跨域HTTP請求
4、window.postMessage
本文先到這里,后續我們再詳細介紹上面提到的4種跨域技術,稍后就奉上!
新聞熱點
疑難解答