介紹
CORS(來源資源共享)是一種瀏覽器安全,用於控制來自一個來源的網頁機制如何請求來自不同來源的資源。當https://app.example.com處的前端嘗試從https://api.example.org取得資料時,瀏覽器預設強制執行同源策略。 CORS提供了一種突破HTTP標頭來放寬此策略的受控方法。本文介紹了完整的CORS流程、預檢請求以及如何修復常見的跨存取阻止錯誤。
同源政策
起源由方案、主機和連接埠的組合定義:
| 網址 | 產地 |
|---|---|
| 佔位符_0 | 佔位符_1 |
| 佔位符_0 | 同源 |
| 佔位符_0 | 不同產地(不同方案) |
| 佔位符_0 | 不同來源(不同主機) |
| 佔位符_0 | 不同產地(不同口岸) |
預設情況下,同源策略將阻止讀取跨來源回應。這可以防止惡意網站竊取其他來源的資料。
簡單請求與預檢請求
CORS區分簡單請求和觸發預檢的請求。
如果滿足所有這些條件,請求就是簡單:
- 方法:
GET、HEAD或POST - 內容類型:
application/x-www-form-urlencoded、multipart/form-data或text/plain - 沒有自訂標頭
對於簡單請求,瀏覽器直接發送請求並檢查回應中的 CORS 標頭。
所有其他請求都會觸發觸發預檢 — 實際上在發送的OPTIONS請求之前:
OPTIONS /api/data HTTP/1.1
Host: api.example.org
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization
伺服器器必須使用適當的 CORS 標頭進行回應,瀏覽器才能繼續。
核心 CORS 回應標頭
伺服器利用這些回應的標頭控制 CORS 行為:
| 標題 | 目的 |
|---|---|
| 佔位允許符_0 | 指定哪些來源 |
| 佔位允許符_0 | 上線的 HTTP 方法 |
| 佔位允許符_0 | 上市的自訂請求標頭 |
| 佔位允許符_0 | 是否權限(cookie) |
| 佔位符_0 | 預檢結果可以緩存多久 |
| 佔位符_0 | 回應的標頭是可存取的 |
預檢的 CORS 回應範例:
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
通配符與特定起源
使用 Access-Control-Allow-Origin: * 允許任何來源,但有限制:
- 不能與
Access-Control-Allow-Credentials: true一起使用 - 僅限公有、唯讀API
對於請求請求,您必須指定目的的來源:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
如果您需要多個允許的來源,伺服器必須根據白名單驗證請求來源後動態回顯請求來源。
使用 CORS 處理 Cookie
要在跨來源請求中包含cookie,客戶端和伺服器都必須選擇加入:
客戶端(JavaScript):
fetch('https://api.example.org/data', {
credentials: 'include', // sends cookies
});
伺服器(回覆標頭):
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
如果沒有 credentials: 'include',cookie 永遠不會跨來源發送。
CORS 常見錯誤及解決方案
| 錯誤訊息 | 可能的原因 | 修復 |
|---|---|---|
| 佔位符_0 | 伺服器上缺少 CORS 標頭 | 新增 Access-Control-Allow-Origin |
| 佔位符_0 | 來源不在允許清單中 | 根據白名單驗證來源 |
| 佔位符_0 | 帶有標誌的通配符 | 使用特定原點而不是* |
| 佔位符_0 | 未上市的方法 | 將 PUT 加入允許的方法 |
| 佔位符_0 | 自編輯標頭不允許標頭中 | 將標題新增至 Access-Control-Allow-Headers |
伺服器器設定範例
Express.js:
const cors = require('cors');
app.use(cors({
origin: 'https://app.example.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true,
}));
Nginx:
add_header Access-Control-Allow-Origin "https://app.example.com";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type";
##結論
CORS 是安全層的關鍵,可以保護用戶,同時實現合法的跨域互動。了解簡單請求和預檢請求之間的差異、了解要配置哪些標頭以及正確的處理依據是全端開發人員的基本技能。貫穿正確設定伺服器的 CORS 策略,您在無法阻止有效跨網域流量的情況下維護安全性。

