當我們把前端 (Render) 跟後端 (Vercel) 分開部署到不同的網域時,瀏覽器基於安全性考量,預設會擋下跨網域的 API 請求,也就是大名鼎鼎的 CORS (Cross-Origin Resource Sharing) 錯誤。今天我們要把這個障礙打通,同時將雲端環境變數設定到位!
OPTIONS 請求為什麼瀏覽器這麼雞婆要擋 CORS?
這源自於瀏覽器的 同源政策 (Same-Origin Policy)。如果不擋,任何惡意網站都可以偷偷在背景用您的瀏覽器身分去打您銀行的 API。
為了解決合法跨網域的需求,W3C 發明了 CORS 協定。如果您打開 F12 的 Network 面板仔細觀察,會發現每次發送 POST 或帶有 Token 的 GET 請求前,瀏覽器都會「偷偷先發送一個叫做 OPTIONS 的請求 (Preflight)」。
這個 OPTIONS 就像是探路尖兵,它會先去問後端:「請問您可以接受來自 Render 網域的請求嗎?」
如果後端點頭 (回傳正確的 CORS Headers),瀏覽器才會真正送出那支 API 請求。
回到我們的後端 src/index.ts,我們需要設定 cors 套件,扮演那個點頭的角色,並把前端的網域加入白名單:
import express from 'express';
import cors from 'cors';
const app = express();
// 1. 設定 CORS,允許來自特定網域的請求
const allowedOrigins = [
'http://localhost:5173', // 本地開發前端網址
process.env.FRONTEND_URL // 雲端前端網址 (例如 https://my-pokemon-app.onrender.com)
].filter(Boolean);
app.use(cors({
origin: allowedOrigins,
credentials: true // 允許前端攜帶 Cookie 或 Authorization Header
}));
// ... 其他路由設定
接著,我們要去雲端平台設定環境變數:
FRONTEND_URL (前端的網址)、TURSO_DATABASE_URL、TURSO_AUTH_TOKEN (資料庫連線資訊)。VITE_API_BASE_URL,設定為 Vercel 的網址 (https://xxx.vercel.app/api)。
CORS policy error:瀏覽器開發者工具 (F12) 裡面的紅字「CORS policy error」報錯。

CORS解決:成功從前端抓取到寶可夢資料的真實網站。
大功告成!前後端終於在雲端順利會師,我們為朋友開發的寶可夢持有追蹤系統已經可以隨時拿起手機操作了!明天,我們將為這 30 天的鐵人賽寫下完結篇的回顧!