Host: api.mydomain.com
Origin: https://www.mydomain.com
[Rest of request...]
  1. 服務器檢查Origin請求標頭。如果 Origin 值被允許,則將 設置Access-Control-Allow-Origin為請求標頭中的值Origin
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.mydomain.com
Content-Type: application/json
[Rest of response...]
  1. 當瀏覽器收到響應時,瀏覽器會檢查標頭以查看其是否與選項卡的來源匹配。如果不匹配,則阻止響應。如果與單一來源完全匹配或包含通配符*運算符,Access-Control-Allow-Origin則檢查通過(如本例所示) 。Access-Control-Allow-Origin

響應的服務器Access-Control-Allow-Origin: *?允許所有來源,這可能帶來很大的安全風險。

僅當您的應用程序絕對需要它(例如創建開放/公共 API)時才使用 *。

意圖

可以看到,服務器可以根據請求的來源來決定是否允許該請求。瀏覽器保證Origin請求標頭的設置可靠且準確。

II. 預先檢查的請求

預檢請求是另一種類型的 CORS 請求。預檢請求是一種 CORS 請求,其中瀏覽器需要在發送預檢請求之前發送預檢請求(即初步探測),以詢問服務器是否可以繼續執行原始 CORS 請求。此預檢請求本身是OPTIONS對同一 URL 的請求。

由于原始 CORS 請求之前有一個預檢請求,因此我們將原始 CORS 請求稱為已預檢

如果出現以下情況,則任何 CORS 請求都必須進行預檢:

來源:?Mozilla

需要預檢請求的典型情況:
  1. 一個網站通過 AJAX 調用 POST JSON 數據到 REST API,這意味著Content-Type標頭是application/json
  2. 網站對 API 進行 AJAX 調用,使用令牌在請求標頭中對 API 進行身份驗證,例如Authorization

這意味著,支持單頁應用程序的 REST API 通常可以對大多數 AJAX 請求進行預檢。

示例流程
  1. 打開瀏覽器選項卡,https://www.mydomain.com 啟動一個POST https://api.mydomain.com/widgets帶有 JSON 有效負載的經過身份驗證的 AJAX 請求。瀏覽器OPTIONS首先發送請求(又稱為預檢請求),其中包含主請求的建議請求方法和請求標頭:
OPTIONS /widgets/ HTTP/1.1
Host: api.mydomain.com
Origin: https://www.mydomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization, Content-Type
[Rest of request...]
  1. 服務器響應并指定允許的 HTTP 方法和標頭。如果原始 CORS 請求旨在發送列表中不存在的標頭或 HTTP 方法,則瀏覽器將失敗,而不會嘗試 CORS 請求。
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.mydomain.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Content-Type: application/json
[Rest of response...]
  1. 由于標頭和方法通過了檢查,瀏覽器將發送原始 CORS 請求。請注意,Origin此請求中也包含標頭。
POST /widgets/ HTTP/1.1
Host: api.mydomain.com
Authorization: 1234567
Content-Type: application/json
Origin: https://www.mydomain.com
[Rest of request...]
  1. 響應在Access-Control-Allow-Origin標頭中具有正確的來源,因此檢查通過并將控制權交還給瀏覽器選項卡。
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://www.mydomain.com
Content-Type: application/json
[Rest of response...]

高級配置


您已經在前面的示例中看到了一些用于 CORS 的標頭,例如Access-Control-Allow-OriginAccess-Control-Allow-Methods,但還有更多標頭可用于更精細的控制。以下是控制 CORS 的標頭的完整列表。

請求標頭

標頭名稱示例值描述用于預檢請求用于 CORS 請求
起源https://www.mydomain.com打開的瀏覽器選項卡的協議、域端口組合是的是的
訪問控制請求方法郵政對于預檢請求,指定原始 CORS 請求將使用的方法是的
訪問控制請求標頭授權,X-PING對于預檢請求,逗號分隔的列表指定原始 CORS 請求將發送的標頭是的

響應標頭

標頭名稱示例值描述用于預檢請求用于 CORS 請求
訪問控制允許來源https://www.mydomain.com服務器指定的允許此請求的來源。如果與Origin標頭不匹配且不是 *,瀏覽器將拒絕該請求。如果指定了域,則協議組件是必需的,并且只能是單個域是的是的
訪問控制允許憑證真的CORS 請求通常不包含 cookie,以防止 CSRF 攻擊。設置為 時true,請求可以使用/將包含 Cookie 等憑據。應省略標頭以暗示falseCORS 請求不會返回到打開的選項卡。不能與通配符一起使用是的是的
訪問控制公開標頭日期,X 設備 ID除了默認標頭之外,還要向瀏覽器選項卡公開其他響應標頭的白名單是的
訪問控制最大期限600Access-Control-Allow-Headers緩存預檢請求結果(即和標頭中的數據)的秒數Access-Control-Allow-Methods。Firefox 的最大值為 24 小時,Chromium 的最大值為 10 分鐘。更高的值不會產生任何影響。是的
訪問控制允許方法獲取、發布、放置、刪除可以是 * 以允許所有方法。逗號分隔的可用于 CORS 請求的允許方法白名單。是的
訪問控制允許標頭授權,X-PING可以是 * 以允許任何標頭。以逗號分隔的允許標頭白名單,可用于 CORS 請求。是的

當前瀏覽器尚未完全實現Access-Control-Allowed-Headers、Access-Control-Allow-Methods 和 Access-Control-Expose-Headers上的通配符 (*) 。
最好列出標頭或方法

常見陷阱

1. 對 Access-Control-Allow-Origin 使用 * 運算符。

CORS 是在嘗試保持安全性的同時放寬同源策略的一種方式。使用 * 會禁用 CORS 的大多數安全規則。有些情況下可以使用通配符,例如集成到許多第三方網站的開放 API。

您可以通過將 API 放在不同的域上來提高安全性。

例如,您的開放 API https://api.mydomain.com可以響應Access-Control-Allow-Origin: * ,但您主網站的 API https://www.mydomain.com/api仍然響應Access-Control-Allow-Origin: https://www.mydomain.com

2. 為 Access-Control-Allow-Origin 返回多個域。

不幸的是,規范不允許Access-Control-Allow-Origin: https://mydomain.com, https://www.mydomain.com。服務器只能使用一個域或 * 進行響應,但您可以利用Origin請求標頭。

3. 使用通配符選擇,如*.mydomain.com

這不是 CORS 規范的一部分,通配符只能用于表示允許所有域。

4. 不包括協議或非標準端口。

Access-Control-Allow-Origin: mydomain.com由于未包含協議,因此無效。

類似地,Access-Control-Allow-Origin: http://localhost除非服務器實際上在標準 HTTP 端口上運行,否則您將遇到麻煩:80

5. Vary 響應標頭中未包含 Origin

大多數 CORS 框架都會自動執行此操作,您必須向客戶端指定服務器響應將根據請求來源而有所不同。

6.未指定 Access-Control-Expose-Headers

如果未包含必需的標頭,CORS 請求仍將通過,但未列入白名單的響應標頭將在瀏覽器選項卡中隱藏。CORS 請求始終公開的默認響應標頭是:

7.當 Access-Control-Allow-Credentials 設置為true時使用通配符

這是一個讓很多人困惑的棘手案例。如果響應包含Access-Control-Allow-Credentials: true,則通配符運算符不能用于任何響應標頭,例如 Access-Control-Allow-Origin。

文章來源:Authoritative guide to CORS (Cross-Origin Resource Sharing) for REST APIs

上一篇:

如何構建 Node.js 中間件來記錄 HTTP API 請求和響應

下一篇:

零一萬物API:釋放大模型潛能,引領AI新紀元
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費