2008年12月13日 星期六

Ajax 跨網域問題的解決之道

Ajax 跨網域問題的解決之道
根據 Same Origin Policy 政策的安全性考量,客戶端的程式碼 (通常是 Javascript) 存在著跨網域存取資料的限制,而好死不死剛好 Ajax 就是屬於這一類型的程式碼。但 Web 2.0 又很流行 Mush Up 把各個不同網站的內容混搭在一起,如果這時候你希望能夠使用 Ajax 來取得來不同網域 (domain) 中的資料,就會遭遇到安全性的問題而無法取得跨網域的資料。

要如何解決 Ajax 跨網域存取資料的問題呢? 既然基本的政策不允許,那麼山不轉就人轉吧! 讓我們耍點小技巧。目前想到的方式有兩種:

一、透過 proxy 程式
這裡所謂的 proxy 並不是大家常聽到網路設定裡面的那個 proxy 伺服器。而是:

1. 自行用 "伺服器端的程式語言" 例如 PHP, ASP.NET 寫一個程式去取得跨網域的資料,這樣的程式我們將它稱為 proxy。因為它是伺服器端的程式,所以當然沒有跨網域的問題。而且在這個程式裡面也可以將取得的資料處理成 JSON 方便給 Ajax 使用。
2. 將這個 proxy 程式放到自己的伺服器上,必須和 Ajax 在同一個網域內。
3. Ajax 不要直接去取得跨網域的資料,因為根本取不到。而改為去跟這個 proxy 程式要資料,所以 proxy 程式就是代替 Ajax 跨網域去取得資料的那個中間人或跳板 (知道為什麼要稱它為 proxy 了吧)。

請特別注意的是: 建議一定要在 proxy 的程式碼中做檢查,呼叫它的程式是否來自於同一個網域,否則每個人都可以寫程式來呼叫你的 proxy,伺服器一定被操翻了 (當然你不介意讓大家公開使用的話也無所謂)。例如 PHP 可以用這段程式碼取得呼叫它的程式的網址:

$referrer = getenv('HTTP_REFERER');

這裡也有現成寫好的 proxy 程式可供使用 http://www.ajax-cross-domain.com/ ,它是使用 Perl 寫的。

二、利用 DOM 動態載入外部 JS 檔案
如果你很幸運,剛好跨網域要讀取的網址所傳回的資料就已經是正確的 JSON 格式了。有可能是自己或別人寫好的 Web API,那麼你可以用這個省時省力又有效率的方法:

1. 用 DOM 動態建立一個 <script> 節點
2. 將這個節點的 file 屬性設成為那個 API 的 URL (可以帶參數)。
3. 這時 API 傳回的內容就會當成是一個外部 JS 檔案直接載入進來了。
然後你便能夠在 Javascript 中直接使用載入進來的 JSON 資料。

這種方法只是利用 <script> 標籤而不是 Ajax,所以壓根不會有跨網域的問題,但一樣可以動態載入外部資料。請特別注意的是: 只有在要動態讀取的資料內容已經是正確的 JSON 格式或 Javascript 程式碼時,才能直接透過動態建立<script> 節點來載入資料哦! 否則的話只能用第一種方法。

第二種方法使用 YUI 裡面的 Get Utility 就能馬上幫您做到。


摘自:http://tw.myblog.yahoo.com/class2u-com/article?mid=1869&prev=2450&next=974&l=f&fid=7

沒有留言:

wibiya widget