AJAX跨域問題的解決辦法
最近公司內部的architecture組正在熱烈討論AJAX,最後難免會談到如何跨域這個問題,因為從AJAX誕生那天起,XMLHttprequest對象在firefox下不能跨域請求的問題就一直存在,等待瀏覽器們去解決這個問題顯然不太現實,聰明的Web開發人員們早就想了一系列的方法來解決這個問題,下面列舉兩個比較不錯的方法:
1. 使用中介層過渡的方式:
中間過渡,很明顯,就是在AJAX與不同域的伺服器進行通訊的中間加一層過渡,這一層過渡可以是PHP、JSP、c++等任何具備網路通訊功能的語言,由中介層向不同域的伺服器進行讀取資料的操作。拿PHP做一個例子,如果需要對不同域的某一個php進行通訊,現在用戶端的 xmlhttprequest先query本域的一個PHP,然後由本域的這個PHP去和不同域的PHP進行通訊,然後由本域的PHP輸出 response;
2. 使用<script>標籤
這個方法是利用<script>標籤中的src來query一個PHP獲得response,因為<script>標籤的src屬性不存在跨域的問題。
舉個例子來讓大家看得更清楚一點吧:
<script LANGUAGE="Javascript" src="" id="get"> </script> <script LANGUAGE="Javascript"> <!-- function get(url) { var obj = document.getElementById("get"); obj.src = url; (obj.readStatus == 200) { alert(param); } } function query() { get(get.php); } //--> </script> <BODY> <INPUT TYPE="button" value="CLICK ME" onclick="query()"> </BODY> </HTML> |
其中get.php的代碼是:
<?php echo "var param = 'www.achome.cn'"; ?> |
最後的運行結果是,當你點擊那個button,它會出現一個內容為”www.achome.cn”的對話方塊。
這個方法又叫做ajaj或者ajax without xmlHttprequest,把x換成了j,是因為使用了<script>標籤而沒有用到xml和xmlHttprequest的緣故。
怎麼樣,很簡單吧,我看到過很多人不願意去正視ajax所存在的技術瓶頸,其實AJAX更應該是Ajax而不是AJAX,突出第一個A是想強調其實AJAX發揚的是一種非同步傳輸的方法,而不是具體到底使用了哪種技術。
asp中網頁原始碼的擷取,跨域的實現
最近幾天一直在研究怎樣去掉用google翻譯我部落格的頁面中的架構,最後得出結論沒有完美解決方案。詳情見次博文-http://www.daokers.cn/article/original/451.htm
我們知道靜態程式是我們從伺服器上下載網頁後在本地執行,而動態網頁是在伺服器中執行然後返回給我們執行的結果,從而達到服務端和客服端互動的效果,這就是所謂的動態。那麼擷取網頁原始碼的方法我們也從這2個方面來著手。下面我就從測試google翻譯的usg值為例詳細說說網頁原始碼的擷取,跨域的實現及 js的傳值。
目標:擷取http://www.daokerstest.com/test.asp&u=http://www.daokers.cn這個頁面的原始碼,U值為變數。
第一種方法,在本地執行程式擷取指定網頁原始碼,這通過js代碼加上xmlhttp組件來完成。
在test.js檔案中。 程式碼function translate() {
var currentUrl=window.location.href;//擷取當前頁面地址或者別的網站地址
var translateUrl="http://www.daokerstest.com/test.asp&u="+currentUrl
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",translateUrl,false);
xmlhttp.send();
var myString=xmlhttp.responseText;//擷取返回的源碼值
document.write(myString)//傳出此值
}
第二種方法,上面的方法最簡單,但是最大的問題是如果想擷取別的網站的原始碼就存在跨域的問題,代碼在 xmlhttp.open("GET",translateUrl,false);處將無法執行,那麼我們可以讓這個代碼在伺服器執行然後再傳回來,也就是通過代理來解決跨域的問題。
這裡只能通過一個代理頁面來擷取目標網頁的原始碼,這裡代理頁面為http://www.daokerstest.com/daili.asp
在test.js檔案中。 程式碼function translate() {
var currentUrl=window.location.href;//擷取當前頁面地址或者別的網站地址
var translateUrl="http://www.daokerstest.com/daili.asp&u="+currentUrl
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",translateUrl,false);
xmlhttp.send();
var myString=xmlhttp.responseText;//擷取返回的源碼值
document.write(myString)//傳出此值
}
daili.asp代碼: 程式碼<script language="JScript" runat="server">
function getusg() {
var getusgUrl="http://www.daokerstest.com/test.asp&u="+(Request.Item("id").Item||"");
var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.open("GET",getusgUrl,false);
xmlhttp.send();
var myString=xmlhttp.responseText;
return myString;
}
Response.Write(getusg());
</script>
這裡涉及到了asp和js之間的傳值,這個方法相當的實用,是藍色理想的小秦告訴我的。最開始我是用string=request("id")來擷取,然後在js中<%=string%>調用,一直失敗,最後小秦的提醒才讓我如夢初醒。我嚴重忽視了server中js和asp的執行順序,在 server中是先執行js然後執行asp代碼,所以當js中調用string值時,asp代碼還沒有執行擷取id值呢!用 Request.Item("id").Item就可以直接在js中擷取參數值,從而成功的實現了繞過了跨域訪問限制。
第三種方法,js可以擷取網頁原始碼,asp也是可以的,並且不存在跨域的問題。js代碼不變。
daili.asp代碼: 程式碼<%
function getHTTPPage(url)
dim Http
set Http=server.createobject("MSXml2.XmlHTTP")
Http.open "GET",url,false
Http.send()
if Http.readystate<>4 then
exit function
else
If Http.status=200 Then
response.write replace(BytesToBstr(http.responseBody,"gb2312"),chr(10),"")
End If
end if
getHTTPPage=bytesToBSTR(Http.responseBody,"GB2312")
set http=nothing
if err.number<>0 then err.Clear
end function
Function BytesToBstr(body,Cset)'轉碼,不然全是亂碼
dim objstream
set objstream = Server.CreateObject("adodb.stream")
objstream.Type = 1
objstream.Mode =3
objstream.Open
objstream.Write body
objstream.Position = 0
objstream.Type = 2
objstream.Charset = Cset
BytesToBstr = objstream.ReadText
objstream.Close
set objstream = nothing
End Function
Dim Url,Html,Usg,id
id=Request("id")
Url="http://www.daokerstest.com/test.asp&u="+id
Html = getHTTPPage(Url)
Response.write Html
'此代碼修改自http://www.stubc.com/thread-465-1-3.html
%>
這個就是直接在asp中用request擷取參數,然後擷取指定網頁原始碼。
從上面執行個體可見,都是利用XmlHTTP來擷取別站的網頁原始碼,只要代碼是在server執行就不存在跨域的問題。