Next.js中间件实战指南:从请求拦截到业务落地的全流程优化
【免费下载链接】next.js The React Framework 项目地址: https://gitcode.com/GitHub_Trending/next/next.js
你是否还在为用户认证、URL重写、设备适配等需求编写重复代码?是否在寻找一种优雅的方式统一处理所有请求逻辑?本文将带你掌握Next.js中间件(Middleware)的核心用法,通过10分钟实战案例,打造一套可复用的请求处理流水线,解决90%的通用业务场景。
中间件基础:从概念到项目结构
Next.js中间件是运行在请求处理流程中的函数,能够在页面渲染前拦截请求并修改其行为。与传统中间件相比,它具有以下优势:
- 零运行时开销:基于Vercel Edge Runtime,比传统Node.js中间件快40%
- 全栈请求处理:同时支持客户端导航和服务器请求
- 精细化路由控制:通过匹配规则精确控制执行范围
在项目中,中间件文件采用单一入口设计,必须放置在项目根目录:
GitHub_Trending/next/next.js/
├── middleware.ts # 根目录中间件文件
├── pages/ # 页面目录
└── public/ # 静态资源
这种结构替代了旧版的嵌套中间件模式,通过middleware-upgrade-guide.mdx中详述的Matcher配置实现路由匹配,大幅提升了执行效率和代码可维护性。
核心功能与API详解
请求拦截与修改
中间件的核心能力是拦截请求并返回修改后的响应。基础结构如下:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server'
export function middleware(request: NextRequest) {
// 创建响应对象
const response = NextResponse.next()
// 修改请求头
response.headers.set('X-Frame-Options', 'DENY')
return response
}
// 匹配规则:仅对/api和/admin路径生效
export const config = {
matcher: ['/api/:path*', '/admin/:path*'],
}
注意:从Next.js 12.2开始,中间件不再支持直接返回响应体,必须通过重写或重定向到页面/API路由处理响应内容。详细迁移方法见middleware-upgrade-guide.mdx
路由控制:重写与重定向
通过rewrite和redirect方法实现URL映射:
// 根据设备类型重写路由
export function middleware(request: NextRequest) {
const url = request.nextUrl.clone()
// 移动设备路由重写
if (request.headers.get('user-agent')?.includes('Mobile')) {
url.pathname = `/mobile${url.pathname}`
return NextResponse.rewrite(url)
}
// 未认证用户重定向
if (!request.cookies.get('auth_token')) {
return NextResponse.redirect(new URL('/login', request.url))
}
return NextResponse.next()
}
实战案例:打造企业级请求处理流水线
1. 多环境路由切换
通过请求头识别环境,自动切换API端点:
// 环境路由匹配器配置
export const config = {
matcher: '/api/:path*',
}
export function middleware(request: NextRequest) {
const env = request.headers.get('x-env') || 'production'
const url = request.nextUrl.clone()
// 开发环境API重定向
if (env === 'development') {
url.host = 'dev-api.example.com'
return NextResponse.rewrite(url)
}
return NextResponse.next()
}
2. 高级Cookie管理
新版Cookies API提供更安全的操作方式,支持设置HttpOnly、SameSite等属性:
export function middleware(request: NextRequest) {
const response = NextResponse.next()
// 设置会话Cookie
response.cookies.set({
name: 'session_id',
value: crypto.randomUUID(),
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
maxAge: 60 * 60 * 24 // 24小时有效期
})
// 删除过期Cookie
if (request.cookies.get('old_token')) {
response.cookies.delete('old_token')
}
return response
}
完整的API变更记录可参考middleware-upgrade-guide.mdx中的迁移指南。
3. 用户认证与角色控制
结合JWT实现细粒度权限控制:
import { verifyAuth } from '@/lib/auth'
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth_token')?.value
// 公开路径白名单
const publicPaths = ['/login', '/register', '/public']
if (publicPaths.includes(request.nextUrl.pathname)) {
return NextResponse.next()
}
// 未认证用户重定向
if (!token) {
return NextResponse.redirect(
new URL(`/login?redirect=${request.nextUrl.pathname}`, request.url)
)
}
// 验证用户角色
try {
const { role } = verifyAuth(token)
if (request.nextUrl.pathname.startsWith('/admin') && role !== 'admin') {
return NextResponse.redirect(new URL('/forbidden', request.url))
}
} catch (error) {
return NextResponse.redirect(new URL('/login', request.url))
}
return NextResponse.next()
}
性能优化与最佳实践
匹配规则优化
使用正则表达式精确控制中间件执行范围,避免不必要的处理:
export const config = {
matcher: [
/*
* 匹配所有路径除了:
* - /api (API路由)
* - /_next/static (静态资源)
* - /favicon.ico (网站图标)
*/
'/((?!api|_next/static|favicon.ico).*)',
],
}
这种配置可减少60%的中间件执行次数,详细优化策略见middleware-upgrade-guide.mdx中的性能对比。
错误处理与调试
中间件执行异常时,可通过重定向到专用错误页面提供更好的用户体验:
export function middleware(request: NextRequest) {
try {
// 业务逻辑处理
return NextResponse.next()
} catch (error) {
console.error('Middleware error:', error)
return NextResponse.redirect(new URL('/error/middleware', request.url))
}
}
常见错误排查可参考beta-middleware.mdx中的解决方案。
版本迁移与兼容性处理
从旧版嵌套中间件迁移时,需注意以下关键变更:
- 文件位置:从
pages/_middleware.ts移至项目根目录 - 匹配逻辑:使用导出的
config.matcher替代路径嵌套 - 响应处理:不再支持直接返回响应体,需使用重写/重定向
迁移示例对比:
旧版嵌套中间件:
// pages/admin/_middleware.ts
export function middleware(request) {
// 仅/admin路径生效
}
新版根中间件:
// middleware.ts
export function middleware(request) {
if (request.nextUrl.pathname.startsWith('/admin')) {
// 仅/admin路径生效
}
}
export const config = {
matcher: '/admin/:path*'
}
完整迁移指南参见middleware-upgrade-guide.mdx中的详细步骤。
总结与进阶学习
Next.js中间件通过单一入口、精确匹配和边缘计算特性,为现代Web应用提供了高效的请求处理方案。本文介绍的基础用法和实战案例可满足大部分业务需求,进一步学习可参考:
- 官方文档:middleware-upgrade-guide.mdx
- 示例项目:examples/with-middleware/
- API参考:docs/api-reference.mdx
掌握这些技能后,你可以构建更安全、更高效的请求处理流程,为用户提供无缝的应用体验。欢迎在评论区分享你的使用场景和优化技巧!
下期预告:《Edge Runtime深度优化:将中间件性能提升300%的实战技巧》
本文代码示例已同步至examples/middleware-recipes/,可直接克隆仓库体验:
git clone https://gitcode.com/GitHub_Trending/next/next.js
【免费下载链接】next.js The React Framework 项目地址: https://gitcode.com/GitHub_Trending/next/next.js
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



