最初是拳 👊
相信大家都知道,Call API 有時會遇到的 CORS (Cross-Origin Resource Sharing) 跨域存取問題。以前還是初學小菜雞的時候(雖然現在還是 😂),這總是讓我很困擾...
之所以說困擾,主要我最在意的是以下兩種狀況:
- 看到很想摳(?)的 API 但摳不了
- 看到又有人 po 面試文,面試題目中須解決跨域存取問題
今天就回顧一下之前我所學的經驗,一次解決上述我心中的傷痛 Q_Q
CORS 與 Proxy
首先必須了解到,跨域存取的限制是來自於 瀏覽器 ,不是源於 API 環境 ;由此為了解決問題,我們可以考慮兩個面向:
- 斷開(x)瀏覽器對 CORS 的限制。
- 創造一個非瀏覽器環境,並使之對應於 API。
針對第二點說明,簡單梳理一下:
遇到問題:Browser ↔ API 因為 CORS 無法存取。
解決方案:以 Browser ↔ Proxy Server ↔ API 的模式繞過 CORS 阻隔進而實踐存取。
解決方案的關鍵核心在於,Browser 和 Proxy Server 在同網域;且 Proxy Server 與 API 互動不是藉由瀏覽器,而是用後端程式,因此最後避開了 CORS 問題。
動手實作啦!
今日取材
- API: https://shibe.online
- CORS Proxy GitHub: https://github.com/ccoenraets/cors-proxy
API & GitHub 套件,連結中都有介紹如何使用。我要用 Browser(前端) Call 我自己用 Node.js 架起來的代理伺服器(Proxy Server),然後 Proxy Server 會將請求轉發至實際的 API Server。
在 cors-proxy
安裝並依照指令鍵入 node server
,代理伺服器會被啟動在 http://localhost:3000
的位置。
隨後我簡單的起了一個專案,並在 JavaScript 寫入 Request 請求。
重點部分是下圖第 1、第 4 行。依據套件需求,我在第 4 行 xhr.setRequestHeader
設定 Header
與 API Server
。並承先前所述,將欲請求之 API 路徑改為 http://localhost:3000/[API]
,如第 1 行所示。
就當我以為要順利完成我的第一個 CORS Proxy demo 的時候,畫面並沒有順利呈現,並跳出了以下錯誤訊息。
老實說第一時間我是不知從何著手,有點傻了 😆。
這也是這次讓我學到的寶貴經驗!這時候可以去 GitHub Repo 裡的 Issues
和 Pull requests
裡看看,其他人的經驗或想法有沒有什麼可以參考的。
這個套件的最大問題之一,顯然是作者已經長時間沒有維護了。但稍微看一下不難發現這次遇到的問題,Code 該從何著手改起。
將 Header
的設定做出修正;把以下 Gist 原本第 5、第 12 行的 Code 改成第 6、第 13 行,主要是把內容改為 Target-Endpoint
的部分。
柴柴華麗登場 🎉
修正後重新啟動 Proxy Server ,畫面即可正確顯示囉!
最初是拳,最後是結論 🐾
關於 CORS / Proxy
- 跨域存取的限制來自於 瀏覽器(Browser) 不是 API 環境 。
- 本文討論的解決方案是以 Browser ↔ Proxy Server ↔ API 的模式繞過 CORS 阻隔進而實踐存取。
關於套件錯誤
- 除了上網 Google 錯誤訊息之外,可以去 Repo 的
Issues
與Pull requests
查看,是否有解決方案或可參考的資訊。
今天的分享也差不多要到一個段落了。以往聽到別人的面試經驗,要臨時架出一個 Proxy Server 感覺會很有時間壓力、很麻煩。但經過這次的學習,若能找到自己慣用的工具,或是修改成屬於自己的套件,在開發的效率上是很有幫助的。
另外就是在這次開發過程中,當發現有些問題是發生在套件上的時候,一時間會有點進入 冒名頂替症候群(Impostor Syndrome) 、有些不知所措。但經過我們家老大的指示,並且學到去 Repo 的 Issues
與 Pull requests
找解方,累積到實務的經驗確實非常寶貴!在此跟大家分享 😄。