1. 前言
前端開發人員寫 JS 遇到需要串接第三方 API,或是想存取第三方網站的資料時,遲早會遇到跨域限制的問題。
跨域(Cross-Origin Resource Sharing)的原理可參考這篇「跨來源資源共用」,因為安全性考量,網站主幾可設定收到 HTTP 請求時,是否允許非主機網域的來源進行存取。例如自架站的圖片若不想被盜連,可以設定不允許其他網域存取。
使用 JS 存取第三方 API 或網站資料時,若對方主機未允許 CORS,那麼前端人員可是一點辦法都沒有,只能求助於後端,利用伺服器端程式來繞過此問題。
但是不太可能每個前端人員都自己架個伺服器,花這麼一大筆費用只為了處理跨域問題。值得慶幸的是,有國外免費服務架設伺服器,幫大家處理跨域存取的問題,本篇就來整理一些可用的選擇。
2. 同源政策(same-origin policy)
在同源政策(same-origin policy)中規範了那寫資源可以跨源存取,哪些會受到限制。
同源的定義簡單如下:
- 不同網域(Domain)
- 不同通訊協定:HTTP, HTTPS, FTP
- 不同連接埠號(Port)
- 一般來說跨來源寫(Cross-origin writes)、跨來源嵌入(Cross-origin embedding)是被允許的,而跨來源讀取(Cross-origin reads)是受限制的。
3. 解決方法
3.1. 後端程式人員幫忙解開限制(開啟跨來源請求)
若要開啟跨來源請求,必須在伺服器端做一些設定,像是在 Response Header 加上 Access-Control-Allow-Origin:
1 | Access-Control-Allow-Origin: * # 允許所有網站發送的請求 |
也就是在後端程式碼要寫開放的規則
3.2. 後端程式碼再包裝第三方API後,給前端調用
如果是第三方的API,沒辦法請對方幫我改後端,那要怎麼辦呢?
另外做個後端再包裝API,讓前端得以調用。這也是最常見的方式。
3.3. 第三方服務代理請求
3.3.1. CORS-ANYWHERE
API 使用很簡單,用以下格式即可:
1 | https://cors-anywhere.herokuapp.com/第三方網址 |
3.3.2. CORSIO
API 使用很簡單,用以下格式即可:
1 | https://cors.io/?第三方網址 |
3.4. JSONP
3.4.1. JSONP 的原理
利用 script 標籤不受同源策略影響,可以跨域引入外部資源的特性,讓服務器端返回可執行的 JS 函數,將要返回的數據作為參數傳進函數,以此實現跨域加載數據的目的
此時,繞過 Ajax,並未使用它,但同樣達成了請求數據的目的
[](【備註】——script 標籤引用資源得本質是:
1)向 src 發送請求
2)將資源下載到當前頁面
3)當資源加載完畢後,把該資源當做 JS 代碼來立刻執行——【備註】)
3.4.2. JSONP 的使用
動態創建 script 標籤,src 地址指向數據接口,並傳遞 callback 參數
定義數據處理函數
服務端接收請求,解析參數,計算數,返回回調函數字符串
將回調函數字符串引入頁面並作為 JS 去執行:此時會調用數據處理函數,數據會作為數據處理函數的參數被處理計算出一個結果