第 7 章:中间件与 Edge Functions(进阶)

64 阅读2分钟

第 7 章:中间件与 Edge Functions(进阶)


7.1 什么是 Middleware?

Middleware 是 Next.js 13+ 引入的一项功能,运行在请求开始阶段,可以在页面渲染之前对请求进行处理。

它的主要作用包括:

  • 用户权限控制(如登录验证)
  • 动态重定向或重写 URL
  • 地域分发 / 语言选择
  • 实现 A/B 测试逻辑
  • 更高效的页面拦截(运行在边缘网络)

7.2 创建中间件文件

你只需要在项目根目录或 app/ 下创建一个名为 middleware.js(或 middleware.ts)的文件:

📄 middleware.js

import { NextResponse } from 'next/server';

export function middleware(request) {
  const token = request.cookies.get('token')?.value;

  if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return NextResponse.next(); // 继续后续流程
}

✅ 匹配路径:

  • 自动应用于所有路由
  • 可配合 matcher 精确指定:
export const config = {
  matcher: ['/dashboard/:path*', '/profile'],
};

7.3 中间件执行时机

中间件会在:

  • 请求发送到页面或 API 路由 之前 执行
  • 不会进入 React 组件内部
  • 运行于 边缘网络(Edge) ,速度非常快

7.4 实现登录权限控制(案例)

需求: 用户访问 /admin 必须登录,否则重定向到 /login

📄 middleware.js

import { NextResponse } from 'next/server';

export function middleware(request) {
  const isLoggedIn = request.cookies.get('auth')?.value === 'true';
  const { pathname } = request.nextUrl;

  if (pathname.startsWith('/admin') && !isLoggedIn) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ['/admin/:path*'],
};

📌 设置 cookie 示例(登录成功时):

// pages/api/login.js
export default function handler(req, res) {
  res.setHeader('Set-Cookie', 'auth=true; Path=/; HttpOnly');
  res.status(200).json({ message: '登录成功' });
}

7.5 URL 重写与重定向(高级用法)

✅ 重写(rewrite):改变路径但保持 URL 不变

export function middleware(request) {
  const url = request.nextUrl.clone();

  if (url.pathname === '/shop') {
    url.pathname = '/store';
    return NextResponse.rewrite(url);
  }

  return NextResponse.next();
}

✅ 重定向(redirect):跳转到新地址(URL 会变化)

export function middleware(request) {
  const url = request.nextUrl.clone();

  if (url.pathname === '/old-page') {
    url.pathname = '/new-page';
    return NextResponse.redirect(url);
  }

  return NextResponse.next();
}

7.6 Edge Functions 与 Middleware 的区别

功能MiddlewareEdge Functions
运行时机请求前自定义 API 路由
文件位置middleware.jspages/api/xxx/route.js
使用场景权限控制、重写、A/B 测试定制化请求处理(更复杂逻辑)
执行位置Vercel 边缘节点(全球 CDN)同样支持 Edge

7.7 示例:A/B 测试

export function middleware(request) {
  const random = Math.random();

  const url = request.nextUrl.clone();

  if (request.nextUrl.pathname === '/') {
    url.pathname = random > 0.5 ? '/version-a' : '/version-b';
    return NextResponse.rewrite(url);
  }

  return NextResponse.next();
}

7.8 常见限制与注意事项

限制项说明
不能访问 React 组件middleware 是运行在服务端、请求前
不支持 fetch() 请求外部数据(需 Edge)必须在 1ms 内返回响应
不支持 Node.js 原生模块运行环境不是 Node,而是 Edge Runtime
cookie 访问为只读想修改 cookie 应在 API 路由中完成

✅ 小结

功能方法
权限控制判断 cookie,拦截请求重定向
URL 重写使用 NextResponse.rewrite()
路由跳转使用 NextResponse.redirect()
匹配规则使用 config.matcher 配置作用路径
执行位置运行在边缘网络,快且轻量
实现 A/B 测试随机决定路径重写方向