Next.js Middleware 與 Edge Runtime:
在邊緣執行你的邏輯
Middleware 攔截請求、Edge Functions、Geolocation 分流 — 讓你的應用響應速度提升到 50ms 以內
Section 1:什麼是 Middleware?為什麼需要它?
Next.js Middleware 是每個請求進入你的 Next.js 應用之前的「守門員」——一段在 Edge Runtime 上執行的程式碼,能在請求到達 Page 或 API Route 之前攔截、修改、或重導向它。由於執行在邊緣節點(離用戶最近的伺服器),延遲通常在 50ms 以內,遠優於傳統 Server-Side 邏輯。
請求處理流程
適合在 Middleware 做的事
身份驗證
在請求到達 Page 之前就判斷用戶是否登入,未登入直接重導向到 /login,不需要在每個 Page 重複寫這個邏輯。
A/B Testing
隨機將用戶分配到 A 或 B 組,用 URL Rewrite 讓他們看到不同版本的頁面,URL 對用戶透明,資料收集由 Middleware 處理。
地理分流(Geolocation)
根據用戶的 IP 位址判斷所在國家,自動導向對應地區的版本(台灣 → /tw、日本 → /jp),無需用戶手動切換。
速率限制(Rate Limiting)
在 Edge 層就擋掉過多請求,保護你的 API 不被濫用,而不需要讓請求跑到 Origin Server 才被擋下。
語言偵測
讀取 Accept-Language Header,自動導向用戶語言的版本(zh-TW → /tw、en → /en),提升國際化體驗。
請求/回應修改
在請求中注入自訂 Header(如 x-user-id、x-country),讓後面的 Page 和 API Route 能直接讀取,無需重複驗證。
Middleware vs API Route vs Server Component — 怎麼選?
Section 2:基礎 Middleware 語法
Middleware 的入口是專案根目錄下的 middleware.ts(與 app/ 資料夾同層),匯出一個 middleware 函式和一個 config(用來控制哪些路徑觸發 Middleware)。
NextResponse.next()
放行請求,繼續正常處理。可以在呼叫前修改 request headers,將資訊傳遞給 Page/API Route。
NextResponse.redirect()
重導向到新 URL,瀏覽器會收到 307/308 回應並發出新請求。URL 會改變,用於身份驗證失敗等情境。
NextResponse.rewrite()
在不改變瀏覽器 URL 的情況下,渲染不同的 Page。用於 A/B Testing、地理分流等需要透明切換的場景。
matcher 的撰寫技巧
- •
/dashboard/:path*— 匹配 /dashboard 及所有子路徑 - •
/((?!_next).*)— 排除以 _next 開頭的路徑(靜態資源) - • 把最常觸發的路徑過濾器放在最前面,節省 Middleware 執行資源
- • 靜態資源(圖片、字體)進入 Middleware 毫無意義,務必排除
Section 3:身份驗證 Middleware
把身份驗證邏輯放在 Middleware 是最理想的做法:一處集中管理,保護所有需要登入的路徑,不需要在每個 Page 或 API Route 重複撰寫。用戶嘗試存取受保護頁面時,Middleware 會在請求到達 Page 之前就判斷並重導向,避免任何受保護內容被渲染。
為什麼在 Middleware 用 jose 而不是 jsonwebtoken?
Middleware 執行在 Edge Runtime,Edge Runtime 不支援 Node.js 的原生 crypto 模組,而 jsonwebtoken 依賴它。jose 是專為 Web 標準 Crypto API 設計的 JWT 程式庫,完全相容 Edge Runtime。
在 Page 中讀取 Middleware 注入的 Header
Section 4:A/B Testing 與 Geolocation 分流
Middleware 的 URL Rewrite 能力讓 A/B Testing 和地理分流的實作變得優雅:用戶看到的 URL 不變,但實際渲染的頁面可以完全不同。這比傳統的 Client-Side A/B Testing(用 JavaScript 在前端切換)更可靠——不會有 Flash of Original Content(FOUC)問題,也不會被 Ad Blocker 干擾。
A/B Testing 實作
你需要額外建立的頁面
- •
app/pricing-A/page.tsx— A 組看到的定價頁(例如:強調年費方案) - •
app/pricing-B/page.tsx— B 組看到的定價頁(例如:強調月費方案) - • 兩個頁面的 URL 對用戶透明,他們看到的都是
/pricing
Geolocation 分流(Vercel Edge Network 提供)
部署在 Vercel 上時,Edge Network 會自動在每個請求中注入地理位置相關的 Header,你在 Middleware 中可以直接讀取,不需要額外的 IP 查詢服務。
Vercel 提供的 Geo Headers
- x-vercel-ip-country — 國家代碼(TW、JP、US)
- x-vercel-ip-country-region — 地區代碼
- x-vercel-ip-city — 城市名稱
- x-vercel-ip-latitude — 緯度
- x-vercel-ip-longitude — 經度
常見 Geolocation 應用場景
- • 自動切換語言版本
- • 顯示當地貨幣與定價
- • 合規性(GDPR / CCPA 通知)
- • 內容授權地區限制
- • 當地特色活動或促銷
Section 5:Edge Runtime 限制與優化
Edge Runtime 是一個輕量化的 JavaScript 執行環境,基於 Web 標準 API(而非 Node.js)。它讓程式碼能在 Cloudflare Workers、Vercel Edge Functions 等邊緣節點執行,全球延遲通常低於 50ms。但輕量化意味著限制——並非所有 Node.js 模組都能在 Edge Runtime 中使用。
❌ 不能在 Edge Runtime 中使用
- • Node.js fs 模組(檔案系統)
- • Node.js net 模組(TCP 連線)
- • jsonwebtoken(依賴 Node.js crypto)
- • bcrypt(原生 addon)
- • 大型 npm 包(bundle size 限制)
- • 直接連接資料庫(Prisma Client 不支援)
✅ 可以在 Edge Runtime 中使用
- • fetch API(HTTP 請求)
- • Web Crypto API(加密)
- • URL、URLSearchParams
- • TextEncoder / TextDecoder
- • jose(Edge 相容的 JWT 庫)
- • cookies()、headers() API
明確指定 Edge Runtime
Edge Runtime 的資料庫存取方案
Middleware 中不能直接連接傳統資料庫(因為 TCP 連線問題)。如果需要在邊緣層做基於資料庫的決策,有幾個常見的替代方案:
基於 HTTP 的 Redis,完全相容 Edge Runtime。適合快取、Session 儲存、Rate Limiting 計數器等需要低延遲讀寫的場景。
Cloudflare 提供的邊緣儲存方案。KV 是鍵值存儲,D1 是 SQLite 資料庫,都可以在 Edge Worker 中直接存取。
將必要資訊(用戶 ID、角色、權限)編碼在 JWT 中,Middleware 直接解析 JWT 取得資訊,完全不需要資料庫查詢。
Section 6:Rate Limiting 在 Middleware 中
速率限制(Rate Limiting)是 API 安全的基本防護,能夠防止暴力破解、DoS 攻擊、以及過度使用 API 的行為。在 Middleware 中實作意味著惡意請求在到達 Origin Server 之前就被擋下,節省運算資源。搭配 Upstash Redis 的 HTTP API,可以在 Edge Runtime 中完整實作滑動視窗計數。
Rate Limiting 演算法比較
Fixed Window
每個固定時間視窗(如每分鐘)重置計數器,實作簡單但在視窗邊界可能被突破。
Sliding Window
根據最近 N 秒內的請求數量限制,比 Fixed Window 更平滑,Upstash 推薦方案。
Token Bucket
以固定速率補充 Token,允許短暫的突發流量,適合需要彈性的 API。
用 Upstash Redis 實作邊緣層速率限制
根據用戶角色設定不同的限流規則
Rate Limiting 最佳實踐
- • 回傳標準的 Retry-After Header
- • 在回應中說明限流原因
- • 對付費用戶提供更高的上限
- • 記錄被擋下的請求以偵測攻擊
常見陷阱
- • 用 IP 限流時,NAT 後的辦公室可能共用 IP
- • x-forwarded-for 可以偽造,高安全場景需要額外驗證
- • 不要在 Middleware 中做太重的計算,否則失去邊緣加速的優勢
Middleware 是 Next.js 全端架構的最後一塊拼圖
把 Middleware 加入你的架構思維後,整個 Next.js 應用的請求處理層次就完整了:Edge Middleware(守門員)→ Server Components(資料獲取)→ Client Components(互動)→ Server Actions(資料變更)。每一層都有明確的職責,整體架構清晰而高效。
上一篇
EP.33 Progressive Web App
Service Worker、Manifest、Offline First
下一篇
EP.35
Coming Soon