CORS Policy

CORS (Cross Origin Resource Sharing),意指在一個網站向不同來源的另一個站發起請求的行為。

瀏覽器預設會封鎖不同來源的請求,確保所有請求來自被信任的網站,稱為 Same-Origin Policy (SOP)。例如你目前已登入 bank.com。若有一個惡意網站 evil.com 執行了 JavaScript 腳本,腳本可能會悄悄地向 api.bank.com 發送請求,並利用瀏覽器自動帶入的 Cookies 來讀取你的帳戶資料。

CORS 的存在正是為了防止這類行為發生。

<aside> ℹ️

URL 結構與「來源」

image.png

一個網址可以大致分爲 protocol, hostname, domain, path 四個部分。

「來源」指的是protocol + hostname + domain

</aside>

用網頁版的 API Client 嘗試向之前寫好的 Todo List API 發送請求,可以觀察到無法成功取得回應,這是因為瀏覽器封鎖了這個請求。打開瀏覽器的開發人員工具可以請求被封鎖的訊息:

image.png

<aside> ℹ️

網頁版的 API Client

簡單的做法:

可以用 Hoppscotch 來發送 Request, Hoppscotch 是操作起來相對簡單的網頁版 API Client。建議使用 Chrome 操作。

Hoppscotch • Open source API development ecosystem

因為一般網頁(不再 localhost 上面的)不允許取用 localhost 的資源,所以在發送請求時瀏覽器可能會詢問「是否允許這個網頁取用裝置上的應用程式」,請按允許。

或是在 Chrome 設定中允許: 設定 > 隱私和安全性 > 網站設定 > 查看各網站的權限及儲存的資料 > hoppscotch.io > 裝置上的應用程式 > 選取「允許」。


進階的做法:

Hoppscotch 是現成的網頁,連上就可以用,但是也因為介面上有許多資源要載入(Script, Icon 等等),開發者面板會出現比較多無關的 Log, 請求等。

付檔 index.html 是一個簡單的網頁版 API Client,可以用 VS Code 的 Live Server 插件啟動,會在 localhost:5500 啟動一個網頁。沒有多餘的資源請求。

index.html

</aside>

<aside> ⚠️

封鎖你的是瀏覽器,不是網路

特別注意,封鎖跨來源請求的是瀏覽器,不是網路或是伺服器。因為絕大部分的網頁都運行在瀏覽器上,所以瀏覽器用這個方法可以保護使用者的安全。因此如果用瀏覽器以外的方式還是可以正常發起請求並取的回應。

</aside>

突破封鎖 信任來源

一般開發上一定會遇到跨來源請求,例如前端網頁和 API 服務在不同位置的時後。在回應時需要讓瀏覽器知道「這個來源是被允許的」

瀏覽器怎麼知道是跨來源請求

在 CORS Policy 的運作當中,有兩個重要的 Header:

下圖可以看到「請求標頭」中有一項 Origin: http://127.0.0.1:5500 表示發出請求的位置,這個標頭由瀏覽器控制,不可修改。

瀏覽器收到回應後會檢查回應的來源,如果和請求是同一個來源,則直接放行。

若是不同來源,則會檢查 Access-Control-Allow-Origin 的值是否和請求來源相同,相同的話瀏覽器才會將回應內容提供給網頁正在執行的程式。

image.png