跳到主要內容
Cypher's Practical Coding
正在準備工作環境...

CORS:瀏覽器為什麼擋你的請求

情境:最讓初學者抓狂的錯誤訊息

你的電商前端(https://shop.example.com)要呼叫一個商品 API(https://api.products.com),程式碼看起來完全正確,但瀏覽器 Console 出現這個紅色錯誤:

Access to fetch at 'https://api.products.com/products' from origin 
'https://shop.example.com' has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

明明用 Postman 測試完全沒問題,為什麼瀏覽器就是不行?


同源政策:公寓大樓的安全規定

什麼是「同源」(Same Origin)?

「源」(Origin)= 通訊協定 + 網域 + 埠號

網址是否同源(和 https://shop.example.com
https://shop.example.com/orders✅ 同源(只是路徑不同)
https://api.example.com/products❌ 不同源(子網域不同)
http://shop.example.com❌ 不同源(協定不同,http vs https)
https://shop.example.com:8080❌ 不同源(埠號不同)
https://other-shop.com❌ 不同源(網域不同)

公寓大樓比喻

把每個網域想成一棟公寓大樓:

  • shop.example.com 是 A 棟
  • api.products.com 是 B 棟

同源政策的規定:A 棟的住戶(瀏覽器中的網頁)不能直接跑去 B 棟拿東西,除非 B 棟的管理員(伺服器)說「A 棟的人可以來」。

這個規定是瀏覽器的安全保護,防止惡意網站偷偷存取你在其他網站的資料。


CORS 是什麼?

CORS(Cross-Origin Resource Sharing)跨來源資源共享 = B 棟管理員貼在門口的「訪客規定」。

如果 B 棟(API 伺服器)的回應 Header 裡有這個:

Access-Control-Allow-Origin: https://shop.example.com

那瀏覽器就會說:「好,這個 API 允許 shop.example.com 來存取,放行。」

如果沒有這個 Header,瀏覽器就擋下來。


Preflight Request:先問再進

當你的 API 請求比較複雜(比如帶了自訂 Header 或用 POST/PUT/DELETE),瀏覽器不會直接送請求,而是先送一個「探路」的請求:

瀏覽器背後實際做的事:

步驟 1:先送 OPTIONS 請求(Preflight)
  OPTIONS https://api.products.com/orders
  Origin: https://shop.example.com
  Access-Control-Request-Method: POST
  Access-Control-Request-Headers: Authorization, Content-Type

步驟 2:API 回應「允許了什麼」
  Access-Control-Allow-Origin: https://shop.example.com
  Access-Control-Allow-Methods: GET, POST, PUT
  Access-Control-Allow-Headers: Authorization, Content-Type

步驟 3:瀏覽器確認可以,才送真正的 POST 請求

這就是為什麼有時候你會在 Network 面板看到兩個請求,一個 OPTIONS 一個 POST。


常見錯誤與修法

錯誤 1:API 完全沒設 CORS Header

錯誤訊息No 'Access-Control-Allow-Origin' header is present

修法:在 API 伺服器加上 CORS Header(後端的工作)

錯誤 2:CORS 設定太寬鬆

* 允許所有來源看起來很方便,但如果你的 API 需要帶 Cookie 或 Authorization,* 是無效的,必須指定具體來源。

錯誤 3:忘了 Preflight 的回應

如果你的 API 有處理 POST 但沒有處理 OPTIONS,Preflight 就會失敗,導致所有複雜請求都被擋下。


重要觀念:CORS 是瀏覽器的機制

Postman 測試沒問題,瀏覽器卻報 CORS 錯誤——這很正常,因為:

CORS 是瀏覽器的安全機制,不是 API 伺服器的機制。

Postman 不是瀏覽器,不受同源政策限制。API 伺服器收到請求是沒問題的,只是瀏覽器在收到回應後,發現沒有被授權的 Header,就把回應擋掉了。

所以解決 CORS 問題,通常要在 API 伺服器端加設定,不是在前端加。


練習題


AI 協作:學了這個,跟 AI 怎麼配合?

理解 CORS 的原理,讓你在遇到 CORS 錯誤時能準確描述問題,AI 就能給出正確的修法。

你的人類優勢:

  • 你知道前端部署在哪個網域、要呼叫哪個 API 網域
  • 你能判斷這個 API 是你們自己控制的(可以改 CORS 設定)還是第三方的(只能繞道)

可以這樣跟 AI 說:

我的前端部署在 https://shop.example.com,要呼叫部署在 https://api.example.com 的 Node.js Express API。瀏覽器報 CORS 錯誤。請幫我在 Express 後端加上正確的 CORS 設定:只允許 shop.example.com 這個來源,需要支援 POST 請求和 Authorization Header。

互動示範

DEMO 1可以修改程式碼試玩
DEMO 2可以修改程式碼試玩

挑戰任務

Task 1

以下哪個情況會觸發 CORS 錯誤? A) 前端在 https://shop.example.com,呼叫 https://shop.example.com/api/orders B) 前端在 https://shop.example.com,呼叫 https://api.orders.com/orders C) 用 Postman 呼叫 https://api.orders.com/orders 請輸入正確答案字母。

Task 2

CORS 錯誤要修,通常是修哪一側的程式碼? A) 前端(React/JS) B) 後端(API 伺服器) C) 兩者都要改 請輸入答案字母。

Task 3

為什麼不建議把 CORS 設成 Access-Control-Allow-Origin: * ?請說明風險。

BackNext Lesson →