Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

瀏覽器 CORS 失敗?分別驗證預檢、實際回應與來源契約

瀏覽器請求可能在 API 呼叫前失敗,也可能在 OPTIONS 成功後或攜帶憑證時失敗。依證據順序定位環節,不要靠猜測堆疊標頭。

顯示 OPTIONS、Origin、Allow 與 Actual 階段的原創 CORS 請求鏈示意圖。
原創示意圖:分別驗證預檢與實際回應。 Watch at Ease

當 curl 或 Postman 可用、瀏覽器 JavaScript 卻回報 CORS 錯誤時,應把它視為一條請求鏈:先確認是否送出預檢,再檢查實際回應是否可讀,最後核對憑證是否要求精確來源。

先擷取瀏覽器請求鏈

開啟開發者工具 Network 面板,保留記錄並只重現一次。判斷瀏覽器是否送出 OPTIONS、是否只送出實際請求,或在抵達伺服器前停止。curl 或 Postman 成功只證明該用戶端可取得 HTTP 回應,不能證明瀏覽器會把跨來源回應交給腳本。

把 OPTIONS 預檢視為獨立交換

若有 OPTIONS,分開檢查請求與回應。請求通常包含 Origin、Access-Control-Request-Method 及必要的 Access-Control-Request-Headers。回應必須允許精確來源、方法與所要求標頭;重新導向、認證挑戰、網路失敗或缺少允許標頭都會阻止實際請求。

再獨立檢查實際回應

預檢通過只允許送出真正請求。實際回應即使是 401、404 或 500,也要帶符合的允許來源標頭才能讓腳本讀取。若本文可讀但自訂回應標頭不可見,檢查 Access-Control-Expose-Headers,而非更改預檢規則。

驗證憑證與來源契約

攜帶 Cookie 或 HTTP 認證時,伺服器不能回覆 Access-Control-Allow-Origin: *;必須回覆精確來源與 Access-Control-Allow-Credentials: true。預檢本身不帶憑證,因此要求 OPTIONS 先認證的中介層會提前阻斷。CORS 也不會覆寫 SameSite 或第三方 Cookie 政策。

檢查動態來源、快取與中介層順序

動態選擇允許來源時加入 Vary: Origin,避免共享快取錯用其他來源的回應。確認 CORS 中介層涵蓋 OPTIONS 與錯誤路徑,而不只在認證或成功路由後執行。以已部署服務的 Network 結果為準。

使用停止分支表

沒有 OPTIONS 也沒有實際請求時先查 URL、混合內容、擴充套件、DNS 或網路層;只有 OPTIONS 就修預檢;兩者都有但腳本不可讀就查實際回應;本文可讀但自訂標頭不可見則只暴露需要的回應標頭。

對照憑證、萬用來源、精確來源與 Vary Origin 的原創示意圖。
原創示意圖:攜帶憑證的請求需要精確允許來源。 Watch at Ease