第五章:前端的宿敵 - 白話解析並解決 CORS 跨域阻擋

這是一個發生在全世界無數個新手前端工程師身上的悲慘故事。

你在上一章完美地寫好了 Axios API 呼叫程式碼,你的 Vite 前端伺服器 (在 localhost:5173 運行) 準備好要向你的 FastAPI 後端伺服器 (在 localhost:8000 運行) 請求熱騰騰的打卡資料。 你滿心歡喜地打開瀏覽器,期待看到那張精美的 Data Table 填滿真實數據。 結果,畫面上永遠停留在「📡 正在從伺服器抓取資料中...」,或是直接噴出紅色的「❌ 無法取得打卡紀錄」。

你慌張地按下鍵盤的 F12 打開開發者工具的 Console,看到了一長串怵目驚心的紅字: Access to XMLHttpRequest at 'http://localhost:8000/api/punches' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

恭喜你!你經歷了前端工程師職涯中最重要的成人禮:被 CORS (跨來源資源共用) 政策給擋在門外了

🎯 本章目標

  1. 用最白話的比喻,聽懂什麼是 CORS?為什麼瀏覽器要這麼無情地擋我?
  2. 釐清觀念:CORS 錯誤到底是前端寫錯,還是後端沒設定好?
  3. 學習如何把紅字錯誤貼給 AI 瞬間解決。
  4. 在 FastAPI 後端正確設定 CORS Middleware,打造安全的名單機制。

🛡️ 什麼是 CORS 跨來源阻擋?(為什麼要這樣搞我?)

很多新手會很生氣:「這兩個伺服器都在我的電腦裡啊!為什麼不能互通?」 其實,這不是你的錯,這是瀏覽器 (Chrome/Safari) 的安全保護機制。這套機制被稱為 同源政策 (Same-Origin Policy)

想像一個極度危險的場景: 假設你今天早上登入了一家網路銀行 (secure-bank.com),你的瀏覽器裡面存了銀行的登入憑證 (Cookie)。 下午,你不小心點開了一個論壇上的惡意釣魚網站 (evil-hacker.com)。 這個惡意網站裡面藏著一段 JavaScript 程式碼,它偷偷地在背景向銀行的網址 (secure-bank.com/api/transfer) 發送了一個「轉帳 100 萬給駭客」的 API 請求。 如果沒有 CORS,因為你的瀏覽器已經有銀行的登入憑證,這筆轉帳真的會成功!你破產了!

為了解決這個漏洞,瀏覽器定下了一個鐵律: 「只要發送請求的網站網址 (localhost:5173),跟接收請求的伺服器網址 (localhost:8000),它們的 Domain (網域) 或 Port (通訊埠) 不一樣,這就被視為『跨網域 (Cross-Origin)』。」 對於跨網域的 API 請求,瀏覽器會很雞婆地先把它擋下來不給過

除非... 接收請求的後端伺服器 (FastAPI) 能夠大聲跟瀏覽器說:「沒關係,localhost:5173 是我同公司的兄弟,我允許他拿資料!」

這就是解決 CORS 的最核心原理:解藥永遠不在前端!必須在後端伺服器設定「白名單 (Allow Origins)」,開放權限給前端!


🚀 實戰:把 Error 貼給 AI,在後端加入白名單

既然知道解藥在後端,我們就不用在 React 裡面瞎忙了。 你不需要去死背 FastAPI 設定 CORS 的複雜語法,只要把你在瀏覽器看到的紅字複製起來,把問題丟給 AI!

🔥【Vibe Prompt 實戰咒語】 我的前端是 Vite + React,運行在 http://localhost:5173。 我的後端是 FastAPI,運行在 http://localhost:8000。 當前端打 API 時,瀏覽器出現了這個報錯: [貼上那串 blocked by CORS policy 的紅字]

我知道這必須在 FastAPI 後端解決。 請給我 FastAPI 需要加入的 CORSMiddleware 程式碼。 請幫我設定允許來源 (allow_origins) 包含本機的 localhost:5173,以及未來可能上線的 Vercel 網址格式。

AI 會立刻看懂你的痛苦,並給你一帖良藥。請回到你的 FastAPI 專案,打開 main.py,把這段程式碼貼在 app = FastAPI() 的正下方:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# 📝 設定白名單:允許哪些網址可以來跟我們要資料?
origins = [
    "http://localhost:5173",           # 本機開發用的 Vite 前端
    "http://127.0.0.1:5173",           # 有時候 Vite 會用這個 IP
    "https://my-line-punch.vercel.app" # 預先寫好未來部署到雲端的前端網址
]

# 🛡️ 在 FastAPI 大門口加上一個 CORS 警衛 (Middleware)
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,     # 把白名單交給警衛
    allow_credentials=True,    # 允許前端帶入驗證憑證 (如 Cookie/Token) 嗎?
    allow_methods=["*"],       # 允許 GET, POST, PUT, DELETE 嗎?("*"" 代表全部允許)
    allow_headers=["*"],       # 允許自訂標頭 (如 Authorization) 嗎?
)

貼上並存檔後,FastAPI 會自動重新載入 (Reload)。 現在,回到你的 Vite 前端網頁,大膽地按下鍵盤的 F5 重新整理。 神奇的事情發生了!紅字消失得無影無蹤,你寫的 loading 轉圈圈結束後,Supabase 資料庫裡面的真實打卡紀錄,完美地填滿了你的 Data Table!


💼 [商業應用場景] 為什麼不要用 allow_origins=["*"]

很多新手在網路上找教學,會看到別人教你把來源設定為 allow_origins=["*"] (允許全世界的網站來拿資料)。 如果你只是在交大學期末報告,這招確實最快,永遠不會報錯。

但如果你在幫企業客戶寫商業系統,這是一個災難級的資安漏洞。 這代表任何駭客、競爭對手,只要寫一個網頁打你的 API,他就能輕易把你公司的員工名單、薪水資料全部撈走,瀏覽器完全不會阻擋他。

這就是 Vibe Coding 提倡的思維:你可以用 AI 快速寫出程式,但你必須知道「這段程式碼的商業風險在哪裡」。堅持使用嚴謹的「網域白名單」,才能保護你與客戶的資產,這也是資深工程師的價值所在。

✅ 本章小結

這章非常重要!未來你在開發生涯的接下來十年內,無論你串接什麼服務,只要你在 Console 看到 blocked by CORS policy 這個字眼。 請你立刻反射性地告訴自己:「這不是我的前端寫錯!這是後端的白名單忘記把我的網址加進去了!

恭喜你跨越了前端最大的障礙。接下來,當我們擁有了真實數據後,純文字的表格看久了也是有點無聊。 下一章,我們將帶你進入數據視覺化的領域,教你用 AI 瞬間畫出讓老闆眼睛一亮的「精美互動式圖表 (Charts)」!

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!