跳转到内容

Next.js中间件

来自代码酷

Next.js中间件[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

Next.js中间件(Middleware)是Next.js路由系统的核心功能之一,允许开发者在请求到达页面之前或之后运行代码。中间件可以用于身份验证、日志记录、重定向、修改请求或响应头等任务。它基于Edge Functions运行,能够在边缘网络(Edge Network)上高效执行。

中间件在Next.js中通过`middleware.js`(或`middleware.ts`)文件定义,并默认应用于项目中的所有路由。开发者可以通过配置来限制中间件的作用范围。

基本用法[编辑 | 编辑源代码]

中间件文件通常位于项目根目录或`src`目录下。以下是一个简单的中间件示例,用于记录请求路径并检查用户身份验证:

// middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  console.log('Request path:', request.nextUrl.pathname);

  // 检查用户是否登录(示例逻辑)
  const isLoggedIn = request.cookies.get('authToken')?.value === 'valid';

  if (!isLoggedIn && request.nextUrl.pathname.startsWith('/dashboard')) {
    // 未登录用户访问/dashboard时重定向到登录页
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return NextResponse.next();
}

输入: 用户访问`/dashboard`页面
输出: 如果未登录(无`authToken` cookie),则重定向到`/login`;否则继续正常渲染页面。

中间件匹配规则[编辑 | 编辑源代码]

默认情况下,中间件会应用于所有路由。可以通过`matcher`配置来限制其作用范围:

// middleware.js
export const config = {
  matcher: [
    '/dashboard/:path*',  // 匹配/dashboard及其子路由
    '/((?!api|_next/static|favicon.ico).*)'  // 排除API路由和静态文件
  ]
};

高级功能[编辑 | 编辑源代码]

修改请求和响应[编辑 | 编辑源代码]

中间件可以修改请求头或响应头:

// 添加自定义响应头
const response = NextResponse.next();
response.headers.set('X-Custom-Header', 'Hello from middleware');
return response;

重写URL[编辑 | 编辑源代码]

可以透明地将请求重定向到不同URL而不改变浏览器地址:

// 将/about重写为/about-us
if (request.nextUrl.pathname === '/about') {
  return NextResponse.rewrite(new URL('/about-us', request.url));
}

边缘函数配置[编辑 | 编辑源代码]

中间件运行在边缘网络,可以指定运行区域:

export const config = {
  runtime: 'edge',  // 指定运行环境
  regions: ['iad1']  // 指定AWS区域
};

实际应用案例[编辑 | 编辑源代码]

案例1:A/B测试[编辑 | 编辑源代码]

使用中间件实现基于Cookie的A/B测试:

// 分配用户到A组或B组
const variant = Math.random() > 0.5 ? 'A' : 'B';
const response = variant === 'A' 
  ? NextResponse.next() 
  : NextResponse.rewrite(new URL('/variant-b', request.url));

// 设置Cookie以便后续识别
response.cookies.set('ab-test-variant', variant);
return response;

案例2:地理封锁[编辑 | 编辑源代码]

根据用户地理位置限制访问:

const country = request.geo.country || 'US';

if (country === 'CN') {
  return new Response('Blocked for your region', { status: 403 });
}
return NextResponse.next();

性能考虑[编辑 | 编辑源代码]

中间件在边缘网络运行,通常具有极低延迟,但需要注意:

1. 避免在中间件中执行复杂计算 2. 合理使用缓存(通过`NextResponse.next()`的`cache`选项) 3. 限制中间件作用范围(通过`matcher`)

常见问题[编辑 | 编辑源代码]

中间件执行顺序[编辑 | 编辑源代码]

Next.js中间件执行流程可以用以下mermaid图表示:

graph TD A[客户端请求] --> B[中间件处理] B --> C{是否重定向/重写?} C -->|是| D[返回修改后的响应] C -->|否| E[继续到页面渲染]

调试技巧[编辑 | 编辑源代码]

1. 使用`console.log`输出调试信息(在Vercel部署中查看日志) 2. 在本地开发时,中间件会在每次请求时重新执行 3. 使用`request.nextUrl`和`request.headers`检查请求详情

数学基础(可选)[编辑 | 编辑源代码]

在某些高级用例中,可能需要计算概率或处理统计信息。例如,A/B测试中的流量分配可以表示为:

P(variant=A)=12,P(variant=B)=12

总结[编辑 | 编辑源代码]

Next.js中间件提供了强大的请求处理能力,特别适合:

  • 身份验证和授权
  • 国际化路由处理
  • 性能优化(如边缘缓存)
  • 实验性功能(如A/B测试)

通过合理使用中间件,开发者可以构建更安全、更灵活且高性能的Next.js应用。