常見的CORS 兩種情況

Willy
4 min readJul 20, 2022

--

跨來源資源共用(Cross-Origin Resource Sharing (CORS))是一種使用額外 HTTP 標頭令目前瀏覽網站的使用者代理 (en-US)取得存取其他來源(網域)伺服器特定資源權限的機制。當使用者代理請求一個不是目前文件來源 — — 例如來自於不同網域(domain)、通訊協定(protocol)或通訊埠(port)的資源時,會建立一個跨來源 HTTP 請求(cross-origin HTTP request)。

通常遇到跨網域問題,大多不是前端可以解決的,當你遇到以後,能明確知道問題在哪時,再與後端夥伴溝通,可以比較快速解決問題,以下為有可能遇到的幾種跨網域情況。

情況一

If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

最常遇到的情況,請後端增加以下header,通常就可以解決:

Access-Control-Allow-Origin: *

Access-Control-Allow-Origin 的值可以帶 *,代表所有網域都可以通過,任何 origin 都合法,也可以帶 origin 像是 http://catcat.tw,代表只有這個 origin 是合法的。

情況二

Access to fetch at ‘http://localhost:3000/' from origin ‘null’ has been blocked by CORS policy: Response to preflight request doesn’t pass access control check

到devtools中 network 去查看 request 的狀況,發現除了原本預期的 POST 以外,還多了一個 OPTIONS 的 request

簡單請求:基本上只要 method 是 GET、POST 或是 HEAD 然後不要帶自訂的 header,Content-Type 也不要超出:application/x-www-form-urlencodedmultipart/form-data 或是 text/plain 這三種。

所以如果Content-Type為 application/json 就不符合簡單請求的定義了。

非簡單請求會多送出一個東西,叫做 preflight request。這個請求就是在devtools中 network 看到的那個 OPTIONS 的 request,針對這個 request,瀏覽器會幫忙帶上兩個 header:

  1. Access-Control-Request-Headers
  2. Access-Control-Request-Method

請求過程:

  1. 我們要送出 POST 的 request 到 http://localhost:3000/
  2. 瀏覽器發現是非簡單請求,因此先發出一個 preflight request
  3. 檢查 response,preflight 通過
  4. 送出 POST 的 request 到 http://localhost:3000/

所以如果 preflight 沒有過,第一個步驟的 request 是不會被送出的,所以錯誤的關鍵字中有preflight就可以優先考慮是否為非簡單請求所造成的cors問題。

解決非簡單請求的方法為,請後端增加以下header:

Access-Control-Allow-Headers: 'content-type'

參考連結

--

--

Willy
Willy

Written by Willy

前端修練筆記本,記錄一些踩雷及學習過程,希望能順便幫助一些,在學習或開發路上卡關的人們。

No responses yet