2018年11月21日

使用跨域代理伺服器(CORS PROXY),解決讀取第三方網站資料問題﹍實作範例

使用跨域代理伺服器(CORS PROXY),解決讀取第三方網站資料問題﹍實作範例

Wayne Fu 0 A+
cors-proxy.jpg-使用跨域代理伺服器(CORS PROXY),解決讀取第三方網站資料問題前端開發人員寫 JS 遇到需要串接第三方 API,或是想存取第三方網站的資料時,遲早會遇到跨域限制的問題。

跨域(Cross-Origin Resource Sharing)的原理可參考這篇「跨來源資源共用」,因為安全性考量,網站主幾可設定收到 HTTP 請求時,是否允許非主機網域的來源進行存取。例如自架站的圖片若不想被盜連,可以設定不允許其他網域存取。

使用 JS 存取第三方 API 或網站資料時,若對方主機未允許 CORS,那麼前端人員可是一點辦法都沒有,只能求助於後端,利用伺服器端程式來繞過此問題。

但是不太可能每個前端人員都自己架個伺服器,花這麼一大筆費用只為了處理跨域問題。值得慶幸的是,有國外免費服務架設伺服器,幫大家處理跨域存取的問題,本篇就來整理一些可用的選擇。



一、跨域存取範例


首先來看幾個範例,瞭解跨域可取得什麼資料:

1. 取得字典翻譯

這篇「誰說前端爬不了資料?使用 crossorigin.me」的作者,想要在自己的網站,直接顯示某翻譯網站的查詢結果,這篇文章也提供了範例程式碼,讀者可自行嘗試。


2. 查詢股票、天氣

這些都是更為實用的功能,直接撈公開資料庫來顯示在自己網站,例如「使用 Yahoo 隱藏版 API 查詢股市資料」。


3. Alexa 網站排名

「Alexa」提供了全世界網站的排名與統計數據,雖然不一定準確,不過至少也是個參考依據。

官方提供了 API 可存取排名數據,例如這個網址可看到 WFU BLOG 的排名:


大致可看到以下的數據資訊:

cors-proxy-1.jpg-使用跨域代理伺服器(CORS PROXY),解決讀取第三方網站資料問題


但若想要執行 jQuery Ajax 來存取這個頁面,瀏覽器會出現 CORS 的錯誤訊息,告知 wfublog.com 不允許進入 alexa.com 的網域:

cors-proxy-2.png-使用跨域代理伺服器(CORS PROXY),解決讀取第三方網站資料問題

接下來會示範如何使用跨域代理伺服器(CORS PROXY)取得 ALEXA 網域的資料。



二、YAHOO 的 YQL


1. 使用教學

Yahoo 的 YQL 算是最佛心的跨域代理服務了,功能超強簡直無法想像,可能是內部工程師有需要而做的工具,卻又免費釋出讓前端工作人員可以輕鬆爬其他網站資料,而且可選擇返為資料格式為 XML 或 JSON。



2. 範例程式碼

現在可以來實作如何取得 ALEXA 資料,首先使用 YQL 的 console 工具:

  • Responses 選 "XML" 可取得的 XML 頁面內容
  • YQL Query 內容填入 select * from xml where url="https://data.alexa.com/data?cli=10&dat=snbamz&url=https://www.wfublog.com/"
  • (補充:如果呼叫第三方 api 取得 json 資料, YQL Query 內容填入 select * from json where url="xxxxx")

cors-proxy-3.png-使用跨域代理伺服器(CORS PROXY),解決讀取第三方網站資料問題

  • 如上圖,YQL 已成功取得 XML 頁面的資料
  • 為了方便 JS 操作,將 Responses 改為 "JSON",重新取得資料
  • 複製 Endpoint 的字串,這裡是 YQL 提供的 API 操作網址

以下為使用 JQUERY 的範例程式碼:

$.getJSON("https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D%22http%3A%2F%2Fdata.alexa.com%2Fdata%3Fcli%3D10%26dat%3Dsnbamz%26url%3Dhttps%3A%2F%2Fwww.wfublog.com%2F%22&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=?", function (data) {
console.log(data);
});

這樣就能輕鬆取得 ALEXA 的 JSON 格式資料囉。



三、CORS-ANYWHERE


1. 使用說明

這是一個簡單、免費的跨域代理伺服器:


API 使用很簡單,用以下格式即可:

https://cors-anywhere.herokuapp.com/第三方網址


2. 範例程式碼

以下為使用 JQUERY 的範例程式碼:

$.get("https://cors-anywhere.herokuapp.com/https://data.alexa.com/data?cli=10&dat=snbamz&url=https://www.wfublog.com/", function (data) {
console.log($(data).find("ALEXA"));
});

  • 這個服務無法像 YQL 一樣,把取得的 XML 頁面轉換為 JSON 格式
  • 我們取回的是一個 XML 物件,可直接用 jQuery 來解析
  • 例如用 find 來找到 <ALEXA> 這個節點。其他節點的資料,可用相同手法來分析及取得


3. 補充

  • 這個服務,比較適合串接第三方 API 服務,且回傳格式為 JS 物件、JSON
  • 這服務較多人使用,因此熱門時段回傳速度比較慢



四、CORS.IO


1. 使用說明

這也是一個簡單、免費的跨域代理伺服器:

  • 官網及說明:https://cors.io/

API 使用很簡單,用以下格式即可:

https://cors.io/?第三方網址


2. 範例程式碼

以下為使用 JQUERY 的範例程式碼:

$.get("https://cors.io/?https://data.alexa.com/data?cli=10&dat=snbamz&url=https://www.wfublog.com/", function (data) {
var xml = $.parseXML(data);
console.log($(xml).find("ALEXA"));
});

  • 這個服務無法像 YQL 一樣,把取得的 XML 頁面轉換為 JSON 格式
  • 這個服務也不像 CORS-ANYWHERE 返回 XML 物件,而是將 XML 整個頁面轉成字串值
  • 所以需要先使用 jQuery 的 parseXML 進行解析
  • 再用 find 來找到 <ALEXA> 這個節點。其他節點的資料,可用相同手法來分析及取得


3. 補充

  • 這個服務一樣比較適合串接第三方 API 服務
  • 從作者文件來看,回傳格式偏好為 JSON 格式



五、其他跨域代理服務


  • 可參考這篇「List of free CORS proxy server」,作者整理了多個 CORS PROXY,並註解使用心得
  • 那麼當讀者發現某個服務失效時,能有其他的替代方案
  • 但不是每個都建議使用,因為 WFU 串接某些第三方 API 時,若網址參數有 2 個或以上的問號 "?" 時,返回結果會造成執行判斷上的錯誤
  • 至少本篇介紹的服務,都是測試後執行上沒有問題的


更多 Javascript 相關技巧:
0 0
如這篇文章對你有幫助,歡迎「分享」到 FB、「追蹤」粉絲團、「訂閱」最新文章

2 則留言:

  1. 请教下,您熟悉cors-anywhere https的部署么?

    回覆刪除
    回覆
    1. 是这样的,我在自己的服务器上安装了cors-anywhere,但是现在只能在ip的情况下使用,但是现在我想实现:
      https://www.xxx.com 这样的效果。现在只能用http,不能用https,请教下。

      刪除

張貼留言注意事項:

◎ 勾選「通知我」可收到後續回覆的mail!
◎ 請在相關文章留言,與文章無關的主題可至「Blogger 社團」提問。
◎ 請避免使用 Safari 瀏覽器,否則無法登入 Google 帳號留言(只能匿名留言)!
◎ 提問若無法提供足夠的資訊供判斷,可能會被無視。建議先參考這篇「Blogger 提問技巧及注意事項」。
◎ CSS 相關問題非免費諮詢,建議使用「Chrome 開發人員工具」尋找答案。
◎ 手機版相關問題請參考「Blogger 行動版範本的特質」→「三、行動版範本不一定能執行網頁版工具」;或參考「Blogger 行動版範本修改技巧 」,或本站 Blogger 行動版標籤相關文章。
◎ 非官方範本問題、或貴站為商業網站,請參考「Blogger 免費諮詢 + 付費諮詢
◎ 若是使用官方 RWD 範本,請參考「Blogger 推出全新自適應 RWD 官方範本及佈景主題」→ 不建議對範本進行修改!
◎ 若留言要輸入語法,"<"、">"這兩個符號請用其他符號代替,否則語法會消失!
◎ 為了過濾垃圾留言,所有留言不會即時發佈,請稍待片刻。
◎ 本站「已關閉自刪留言功能」。

TOP