middleware.js

middleware.js|ts 文件用于编写 中间件 (Middleware) 并在请求完成前在服务端运行代码。根据传入的请求,您可以通过重写、重定向、修改请求或响应头,或直接响应来修改返回内容。

中间件在路由渲染前执行,特别适用于实现自定义服务端逻辑,例如身份验证 (authentication)、日志记录 (logging) 或处理重定向 (redirects)。

在项目根目录下使用 middleware.ts(或 .js)文件来定义中间件。例如,与 apppages 同级,或在 src 目录内(如适用)。

import { NextResponse, NextRequest } from 'next/server'

// 如果内部使用 `await`,此函数可标记为 `async`
export function middleware(request: NextRequest) {
  return NextResponse.redirect(new URL('/home', request.url))
}

export const config = {
  matcher: '/about/:path*',
}
import { NextResponse } from 'next/server'

// 如果内部使用 `await`,此函数可标记为 `async`
export function middleware(request) {
  return NextResponse.redirect(new URL('/home', request.url))
}

export const config = {
  matcher: '/about/:path*',
}

导出内容

中间件函数

文件必须导出一个单独的函数,可以是默认导出或命名为 middleware。注意,不支持从同一文件导出多个中间件。

middleware.js
// 默认导出的示例
export default function middleware(request) {
  // 中间件逻辑
}

配置对象 (可选)

可选地,可以导出一个与中间件函数并列的配置对象。该对象包含 匹配器 (matcher) 以指定中间件应用的路径。

匹配器 (Matcher)

matcher 选项允许您指定中间件运行的特定路径。可以通过以下方式定义路径:

  • 单一路径:直接使用字符串定义路径,例如 '/about'
  • 多个路径:使用数组列出多个路径,例如 matcher: ['/about', '/contact'],这将使中间件同时应用于 /about/contact

此外,matcher 支持通过正则表达式定义复杂路径,例如 matcher: ['/((?!api|_next/static|_next/image|.*\\.png$).*)'],从而精确控制包含或排除的路径。

matcher 选项还接受包含以下键的对象数组:

  • source:用于匹配请求路径的路径或模式。可以是直接路径匹配的字符串,或用于复杂匹配的模式。
  • regexp(可选):一个正则表达式字符串,基于 source 微调匹配。它提供了对包含或排除路径的额外控制。
  • locale(可选):当设置为 false 时,忽略基于区域设置 (locale) 的路由匹配。
  • has(可选):指定基于特定请求元素(如标头、查询参数或 Cookie)存在的条件。
  • missing(可选):关注某些请求元素缺失的条件,例如缺少的标头或 Cookie。
middleware.js
export const config = {
  matcher: [
    {
      source: '/api/*',
      regexp: '^/api/(.*)',
      locale: false,
      has: [
        { type: 'header', key: 'Authorization', value: 'Bearer Token' },
        { type: 'query', key: 'userId', value: '123' },
      ],
      missing: [{ type: 'cookie', key: 'session', value: 'active' }],
    },
  ],
}

参数

request

定义中间件时,默认导出函数接受一个参数 request。该参数是 NextRequest 的实例,表示传入的 HTTP 请求。

import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // 中间件逻辑写在这里
}
export function middleware(request) {
  // 中间件逻辑写在这里
}

须知

  • NextRequest 是表示 Next.js 中间件中传入 HTTP 请求的类型,而 NextResponse 是用于操作和返回 HTTP 响应的类。

NextResponse

中间件可以使用 NextResponse 对象,它扩展了 Web Response API。通过返回 NextResponse 对象,您可以直接操作 Cookie、设置标头、实现重定向和重写路径。

须知:对于重定向,您也可以使用 Response.redirect 替代 NextResponse.redirect

运行时 (Runtime)

中间件默认使用 Edge 运行时 (Edge Runtime)。如果不希望使用此运行时,可以使用 完整的 Node.js 运行时 来运行中间件。

版本历史

版本变更
v13.1.0添加了高级中间件标志
v13.0.0中间件可以修改请求头、响应头并发送响应
v12.2.0中间件功能稳定,请参阅 升级指南
v12.0.9在 Edge 运行时中强制使用绝对 URL (PR)
v12.0.0添加了中间件 (Beta)