Next.js 中的 Edge Middleware 实战
Edge Middleware 是运行在 Vercel 边缘节点的轻量级函数,用于在请求到达页面之前执行逻辑处理,适合用于重定向、鉴权、A/B 测试、国际化等高性能场景。
🧠 1. 什么是 Edge Middleware?
-
✅ 运行位置:运行在边缘节点(Edge Network)上
-
✅ 运行时环境 :使用 Web 标准 API,无 Node.js 原生模块(如
fs
、process
等) -
✅ 触发时机:在请求路由到页面或 API 之前
-
✅ 主要用途:
- 动态重定向 / URL 重写
- 鉴权处理(如未登录跳转登录页)
- 地理位置识别(Geo IP)
- 实现 A/B 测试
- 国际化路由逻辑优化
🏗️ 2. 如何使用 Edge Middleware?
📁 创建中间件文件:
根目录新建文件:
bash
middleware.ts
或指定路径下使用中间件:
bash
pages/
├── dashboard/
│ └── middleware.ts ✅ 仅对 dashboard 下的页面生效
🧪 示例:拦截未登录用户并跳转登录页
ts
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value;
// 如果没有登录 token 且访问的是受保护页面,跳转登录页
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
const loginUrl = new URL('/login', request.url);
return NextResponse.redirect(loginUrl);
}
return NextResponse.next(); // 允许通过
}
🌍 示例:基于地理位置的重定向
ts
export function middleware(request: NextRequest) {
const country = request.geo?.country || 'US';
if (country === 'CN') {
return NextResponse.redirect(new URL('/cn', request.url));
}
return NextResponse.next();
}
✅ 注意:此功能仅在 Vercel 部署时支持 Geo IP(默认启用)
🔀 示例:A/B 测试流量分流
ts
export function middleware(request: NextRequest) {
const abGroup = request.cookies.get('ab-group')?.value;
if (!abGroup) {
const randomGroup = Math.random() > 0.5 ? 'A' : 'B';
const response = NextResponse.rewrite(new URL(`/test-${randomGroup}`, request.url));
response.cookies.set('ab-group', randomGroup);
return response;
}
return NextResponse.rewrite(new URL(`/test-${abGroup}`, request.url));
}
⚙️ 3. 配置匹配条件(matcher)
通过 middleware.ts
中导出配置控制哪些路径匹配中间件逻辑:
ts
export const config = {
matcher: ['/dashboard/:path*', '/profile'],
};
支持:
- 动态参数:
/dashboard/:path*
- 精确匹配:
/login
- 通配符:
/(api|admin)/:path*
🛑 4. 中间件限制与注意事项
限制项 | 描述 |
---|---|
❌ 无法访问 Node.js API | 如 fs 、crypto 、Buffer |
❌ 不能访问数据库 | 只能做轻量判断逻辑 |
❌ 响应体不可修改 | 不能直接渲染页面 |
✅ 可以设置 Cookie | 使用 response.cookies.set() |
✅ 支持缓存头 / 重写 / 重定向 |
📦 5. 示例应用:基于登录状态展示不同导航菜单
ts
export function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value;
request.headers.set('x-authenticated', token ? 'true' : 'false');
return NextResponse.next({
request: {
headers: request.headers,
},
});
}
然后在页面中读取:
ts
export async function getServerSideProps(context) {
const isAuth = context.req.headers['x-authenticated'] === 'true';
return { props: { isAuth } };
}
🚀 6. 发布到 Vercel 使用 Middleware
- Middleware 仅在 Vercel 上自动启用
- 不需要手动配置 server
- 支持 300+ 地理位置边缘节点,响应极快
✅ 小结
功能 | 是否支持 | 推荐用途 |
---|---|---|
重定向 | ✅ | 登录跳转 / 国家跳转 |
路由重写 | ✅ | A/B 测试 / 白名单路由 |
请求封锁 | ✅ | 权限控制 |
修改响应体 | ❌ | 不支持 |
调用数据库 | ❌ | 不支持 |
运行位置 | 🌍 Edge(非 Node) | 延迟低、速度快 |