AJAX不能跨域訪問是什么意思,我想沒有親自遇到這個問題的人,可能根本就不理解.現在我給出一個例子,讓大家體會一下什么是跨域訪問.這個頁面就是一個HTML文件,源碼我附文章后面了.
注:這個頁面并不高深,例子只有一個HTML頁面,沒有引用什么特別的庫之類的.例子的目的只是讓對AJAX不能跨域訪問有一個感性的認識.就好比,你如何告訴一個沒見過汽車的人,告訴他什么是汽車,講半天,還不如直接給個汽車給他看看,他就知道什么是汽車了.但你要他直接給一個清晰的定義,或者是讓他明白汽車的動力學,這就是很難的了,也不是本文的目的.
下面這個簡單的代碼只要復制到一個本地html文件中即可,就可以把任何URL指定的網頁顯示出來[注1],但是同樣的頁面,你如果放到tomcat之類的容器下面,就無法打開,甚至通過網絡鄰居訪問都不行.
?
分析1:為什么好好的頁面卻得不到期望的結果:
為什么JS語法沒有什么問題,放在網絡鄰居與web容器中就不能正常運行了呢,這就是AJAX所說的不能跨域訪問,因為瀏覽器你這個JS程序是來自容器,它就限制你只能正常訪問同一容器里的的資源[注:2],比如你通過http://www.openj.cn訪問到一個頁面,那么這個頁面的JS就只能訪問openj.cn的資源,而不能訪問www.baidu.com.
為什么IE在通過本地文件能正常運行這個頁面的,我是在XP下測試的,可能IE把本地這個域處理成了一個特殊的域,從這個域得到的JS程序,權限可以略微放松些,這樣可能易用性就會好些,要知道安全性與使用的方便性可是此消彼長的關系.所以IE選擇了易用性,在安全問題上放了一個黃燈,為什么說是黃燈呢,因為它在運行這個頁面時,IE會給出一個安全提示,告訴你這個頁面存在風險.
分析2:為什么要限制AJAX跨域訪問[注3]:
可以肯定的說是出于安全的需要,但我沒有找到什么資料明確這個問題分析,我只能通過看其它資料來自己體會了,我自己發現的一個安全問題就是:
AJAX可能會把用戶的cookie信息泄漏出去,比如我往別用戶的Gmail信箱里面發嵌有JS腳本的郵件.這些腳本讀取gmail.com域中的cookies信息,然后通過AJAX發送給我的個人網站,這樣我的個人網站就可以得到這個用戶的Gmail的cookies.我然后把它提取出來,我就可以不用密碼來訪問這個用戶的Gmail郵箱了.
這個只是我能想到的,我想如果能夠讓AJAX能夠跨域訪問的話,肯定還有其它一些安全問題.
注
[1];對這個測試頁面好像只有在一種情況下才能正常執行:就是通過IE打開本地文件。如果用FireFox就算是通過本地文件打開它也不能正常運行。
[2]:為了把問題簡單說明,我說了只能訪問同一容器里面的資源,實際上是不精確的,真正的還是應該通過域來區分,同一個容器里面的資源也可能是指向不同的域.同一個域的各個資源也可能分布在不同的容器中.比如:tomcat中有好2個虛擬目錄,你用不同的域名來指向這兩個虛擬目錄,這個容器中的兩個虛擬目錄就是不同的域了.不同容器的資源也可能屬于同一個域,比如我申請一個域名:openj.cn,我設置 www.openj.cn指向www.baidu.com,而blog.openj.cn指向www.google.com。這樣baidu與google的首頁就都屬于openj.cn這個域了.
[3]: 本文沒有區分AJAX的跨域與JS的跨域,因為AJAX就是通過JS來發現請求的,它們實際上是一回事。
[4]: 在代碼中,我定義了變量 var url = 'http://www.google.com';??? 你可以把它修改為任何你能訪問的地址,
[5]:本文的內容全是自己的瞎體會的,如果有什么不對的有高手發現了,希望大家能指出。這也是本文的主要目的。
?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<HTML xmlns="<HEAD><TITLE>AJAX跨域驗證</TITLE>
<script>
var xmlHttp;
function createXMLHttpRequest() {
??? if (window.ActiveXObject) {
??????? xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
??? }
??? else if (window.XMLHttpRequest) {
??????? xmlHttp = new XMLHttpRequest();
??? }
}
function hello() {
?var url = 'http://www.google.com';???
?createXMLHttpRequest();
?xmlHttp.onreadystatechange = showResponse;
?xmlHttp.open("GET", url, true);
?xmlHttp.send(null);
}
function showResponse(){
? if(xmlHttp.readyState == 4) {
?if(xmlHttp.status == 200) {????????
?document.getElementById("result").setAttribute("value",xmlHttp.responseText) ;
?}
?}
}
</script>
</HEAD>
<BODY>?
?<input type="button" value="hello" onclick="hello()"><br/><br/>
?<textarea id="result" name="result" cols=100 rows=100 ></textarea>
</BODY>
</HTML>
?
?
?
?