JavaScript 抓取跨網域外的資料

現在有非常多的 Open API 可以拿來玩, 但是 JavaScript 無法跨網域的問題還蠻麻煩的, 下面就把抓跨網域資料的方法整理一下.

抓自己網域的資料

先假設目錄下有 data.txt, 內容如下:

hello world

JavaScript 抓取資料的方式如下: (下述範例程式是 jQuery 的 AJAX 寫法)


$.get("data.txt", function(data) {
alert("Data Loaded: " + data); // 執行會跳出 Data Loaded: hello word 的視窗
});


$.get("http://SAME-DOMAIN/data.txt", function(data) {
alert("Data Loaded: " + data); // 執行會跳出 Data       Loaded: hello word 的視窗
});

但是此方法在遇到不同 DOMAIN(Cross Domain) 的狀況就抓不到資料, 因為 Javascript 本身對安全性的限制, 無法抓取本身網域以外的資料, 就算是 www.same-domain 也不行, 一定要完全一樣的 Domain 才行.

抓跨網域的資料

通常都是在 同樣的 DOMAIN 下面寫一隻 proxy.php, 內容大致如下:


<?php
if (isset($_GET['url']) && !empty($_GET['url'])) {
// 記得檢查此 URL 是不是你發出的 request
echo file_get_contents($_GET['url']);
}
?>

使用 Proxy.php 的方法

透過 proxy.php 去抓取跨網域的資料, 範例如下:


$.get("proxy.php?url=http%3A%2F%2FSAME-DOMAIN%2F", function(data) {
alert("Data Loaded: " + data); // Data Loaded: hello world
});

使用 JavaScript src 載入

另外一種做法是透過 script 的 src 直接將資料塞進去, 這種方法就可以由多個不同網域直接取得資料, 不過寫法會有點不同, 格式要是 JSON 或 Javascript code 的格式, 例如:

data.txt 的內容:


var data = "hello world";

使用 src 抓取資料的範例:


<script type="text/javascript" src="http://OTHER-DOMAIN/data.txt"></script>
<script>
alert(data); // hello world
</script>

使用 src 直接抓取的方法, 少掉 PHP 那一層, 可以再想想有什麼地方可以拿來應用~ 🙂

相關網頁

作者: Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.

在〈JavaScript 抓取跨網域外的資料〉中有 18 則留言

  1. 請問Tsung大哥:
    如果對同一個網站,一般網頁資料透過http傳送,而比較重要的資料透過https傳送,例如在XMLHttpRequest的open()裡面直接塞https,是不是也會遇到cross-domain的問題?請問有什麼方式可以解決呢?謝謝

  2. Mmm... 這個我倒是沒試過, 不過 https 還透過 ajax 有點怪, 我現在手上沒有 ssl 的環境可以測試.
    或許您可以試看看? 把我上面的程式一個跑 http, 另一個跑 https 試試看??
    然後分享一下??

  3. 於 localhost 的 proxy.php 去做 post 動作(我上面寫的只是用 GET 拉資訊, 用 POST 可以透過 CURL 等方式去做).
    然後 Javascript 再去跟 proxy.php 要資料即可.

  4. 假設A是Clinet B和C則是不同網域的兩台主機
    B的腳色類似Agent 意即A的request都由B向C要 固存在cross-domain的問題
    用Tsung大哥的proxy範例可以成功解決B向C要資料的問題 如下(remoteCall是一個基本的xmlhttprequest)
    remoteCall("proxy.php", "POST", "url=https%3A%2F%2Fother_domanin%2Ftest_cross_domain.php?command=write");
    其中 B和C之間可以直接用https傳遞
    現在遇到的問題是 A和B之間的資料傳遞 也想要透過https 第一個想到的就是把https直接放到進去 如下
    remoteCall("https://SAME-DOMAIN/proxy.php", "POST", "url=https%3A%2F%2FOTHER-DOMAIN%2Ftest_cross_domain.php?command=write");
    FireBug出現"Access to restricted URI denied" code: "1012"
    IE則是"沒有使用權限"
    其實最簡單的解決方法就是A在網址直接以https去瀏覽 可惜project不接受這種做法(不要問我為什麼 我只是小小工程師 :P)

  5. 嗯嗯, 我原本猜想, 應該是沒有權限, 再不然應該就是拉到一串亂碼才對.
    因為 https 是經過加密的東西, 如果用這種方法走, 似乎有點危險(別人可以讓你登入一個 http 的網頁, 然後幫你送到 https 的頁面去做信用卡付款等動作, 感覺有點危險~ 😛

  6. 说的很好,弄懂了 使用 src 抓取資料的方式
    原来是这样啊。谢谢分享。
    但是如果我POST提交的域是我不可控制的,它返回的是xml数据。我该如何用javascript接收?

  7. POST 資料, 只能跟他同 Domain 的才可以丟過去, 不同 Domain 的就不行.
    你得在 script src 裡面把這些事情做掉, 不然就得透過 php 幫你做.

  8. 我要捉http://ip/php/select.php的json格式
    採用script src的方式,還是無法取得...何解?

    alert(select);

    什麼東西都印不出來

  9. 我要捉的http網頁是一段json數據,但開頭沒有“var 变量名 =”這一段,想採用
    您script src的方式,但這種方式好像只能當網頁中有“var 变量名= 。。。”时才能使用,請問您 我該怎麽在script引用進來後在這個json数居前加上”var 变量名= “?謝謝!

    1. 沒辦法在後面加上, 需要前面就加上, 不然這樣子作的話, 就可以由外部串改全域變數, security 是會有問題的.

victor 發表迴響取消回覆

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料