
Node.js 后端開發指南:搭建、優化與部署
Host: api.mydomain.com
Origin: https://www.mydomain.com
[Rest of request...]
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...]
Access-Control-Allow-Origin
則檢查通過(如本例所示) 。Access-Control-Allow-Origin
響應的服務器Access-Control-Allow-Origin: *?
允許所有來源,這可能帶來很大的安全風險。
僅當您的應用程序絕對需要它(例如創建開放/公共 API)時才使用 *。
可以看到,服務器可以根據請求的來源來決定是否允許該請求。瀏覽器保證Origin
請求標頭的設置可靠且準確。
預檢請求是另一種類型的 CORS 請求。預檢請求是一種 CORS 請求,其中瀏覽器需要在發送預檢請求之前發送預檢請求(即初步探測),以詢問服務器是否可以繼續執行原始 CORS 請求。此預檢請求本身是OPTIONS
對同一 URL 的請求。
由于原始 CORS 請求之前有一個預檢請求,因此我們將原始 CORS 請求稱為已預檢。
來源:?Mozilla
Content-Type
標頭是application/json
Authorization
這意味著,支持單頁應用程序的 REST API 通常可以對大多數 AJAX 請求進行預檢。
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...]
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...]
Origin
此請求中也包含標頭。POST /widgets/ HTTP/1.1
Host: api.mydomain.com
Authorization: 1234567
Content-Type: application/json
Origin: https://www.mydomain.com
[Rest of request...]
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-Origin
和Access-Control-Allow-Methods
,但還有更多標頭可用于更精細的控制。以下是控制 CORS 的標頭的完整列表。
標頭名稱 | 示例值 | 描述 | 用于預檢請求 | 用于 CORS 請求 |
---|---|---|---|---|
起源 | https://www.mydomain.com | 打開的瀏覽器選項卡的協議、域和端口組合 | 是的 | 是的 |
訪問控制請求方法 | 郵政 | 對于預檢請求,指定原始 CORS 請求將使用的方法 | 是的 | 不 |
訪問控制請求標頭 | 授權,X-PING | 對于預檢請求,逗號分隔的列表指定原始 CORS 請求將發送的標頭 | 是的 | 不 |
當前瀏覽器尚未完全實現Access-Control-Allowed-Headers、Access-Control-Allow-Methods 和 Access-Control-Expose-Headers上的通配符 (*) 。
最好列出標頭或方法。
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
不幸的是,規范不允許Access-Control-Allow-Origin: https://mydomain.com, https://www.mydomain.com
。服務器只能使用一個域或 * 進行響應,但您可以利用Origin
請求標頭。
這不是 CORS 規范的一部分,通配符只能用于表示允許所有域。
Access-Control-Allow-Origin: mydomain.com
由于未包含協議,因此無效。
類似地,Access-Control-Allow-Origin: http://localhost
除非服務器實際上在標準 HTTP 端口上運行,否則您將遇到麻煩:80
。
大多數 CORS 框架都會自動執行此操作,您必須向客戶端指定服務器響應將根據請求來源而有所不同。
如果未包含必需的標頭,CORS 請求仍將通過,但未列入白名單的響應標頭將在瀏覽器選項卡中隱藏。CORS 請求始終公開的默認響應標頭是:
這是一個讓很多人困惑的棘手案例。如果響應包含Access-Control-Allow-Credentials: true
,則通配符運算符不能用于任何響應標頭,例如 Access-Control-Allow-Origin。
文章來源:Authoritative guide to CORS (Cross-Origin Resource Sharing) for REST APIs