You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Next.js中通过middleware.ts文件使用多个中间件

在Next.js中无依赖实现多中间件的正确方式

Next.js官方并不支持你尝试的那种导出middleware数组的写法,要实现多个中间件逻辑,以下是三种无需外部包的可行方案:


方案1:单文件内按路径分支处理

这是最直接的方式,在主middleware函数中根据请求路径匹配对应逻辑:

import { NextResponse, NextRequest } from "next/server";

// 拆分独立的中间件逻辑函数
function profileMiddleware(request: NextRequest) {
  const userId = request.cookies.get("userId");
  if (!userId) {
    return NextResponse.redirect(new URL("/auth/login", request.nextUrl.origin));
  }
  return NextResponse.next();
}

function authMiddleware(request: NextRequest) {
  const userId = request.cookies.get("userId");
  if (userId) {
    return NextResponse.redirect(new URL("/", request.nextUrl.origin));
  }
  return NextResponse.next();
}

// 主middleware入口
export function middleware(request: NextRequest) {
  const path = request.nextUrl.pathname;

  // 匹配/profile开头的路径
  if (path.startsWith("/profile")) {
    return profileMiddleware(request);
  }

  // 匹配/auth开头的路径
  if (path.startsWith("/auth")) {
    return authMiddleware(request);
  }

  // 其他路径直接放行
  return NextResponse.next();
}

// 配置需要拦截的所有路径规则
export const config = {
  matcher: ["/profile/:path*", "/auth/:path*"],
};

方案2:链式调用中间件(支持多逻辑串联)

如果需要对同一路径执行多个校验逻辑(比如先登录校验再权限校验),可以写一个简单的组合工具函数实现链式执行:

import { NextResponse, NextRequest } from "next/server";

// 定义中间件类型
type Middleware = (request: NextRequest) => NextResponse | Promise<NextResponse>;

// 中间件组合工具:依次执行中间件,遇到非next响应则终止
function chain(middlewares: Middleware[]) {
  return async (request: NextRequest) => {
    for (const middleware of middlewares) {
      const response = await middleware(request);
      if (response !== NextResponse.next()) {
        return response;
      }
    }
    return NextResponse.next();
  };
}

// 示例:登录校验中间件
function authCheck(request: NextRequest) {
  const userId = request.cookies.get("userId");
  if (!userId) {
    return NextResponse.redirect(new URL("/auth/login", request.nextUrl.origin));
  }
  return NextResponse.next();
}

// 示例:Profile权限校验中间件
function profilePermissionCheck(request: NextRequest) {
  const userId = request.cookies.get("userId")?.value;
  const targetProfileId = request.nextUrl.pathname.split("/")[2];
  if (userId !== targetProfileId) {
    return NextResponse.redirect(new URL("/", request.nextUrl.origin));
  }
  return NextResponse.next();
}

// 主middleware入口
export function middleware(request: NextRequest) {
  const path = request.nextUrl.pathname;

  if (path.startsWith("/profile")) {
    // 链式执行多个中间件
    return chain([authCheck, profilePermissionCheck])(request);
  }

  if (path.startsWith("/auth")) {
    const userId = request.cookies.get("userId");
    if (userId) {
      return NextResponse.redirect(new URL("/", request.nextUrl.origin));
    }
    return NextResponse.next();
  }

  return NextResponse.next();
}

export const config = {
  matcher: ["/profile/:path*", "/auth/:path*"],
};

方案3:多文件拆分中间件(Next.js 13.1+)

如果追求模块化,Next.js支持创建多个独立的中间件文件,每个文件负责对应路径的逻辑:

比如项目结构:

your-project/
├─ middleware/
│  ├─ profile.ts
│  └─ auth.ts

middleware/profile.ts

import { NextResponse, NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  const userId = request.cookies.get("userId");
  if (!userId) {
    return NextResponse.redirect(new URL("/auth/login", request.nextUrl.origin));
  }
  return NextResponse.next();
}

export const config = {
  matcher: "/profile/:path*",
};

middleware/auth.ts

import { NextResponse, NextRequest } from "next/server";

export function middleware(request: NextRequest) {
  const userId = request.cookies.get("userId");
  if (userId) {
    return NextResponse.redirect(new URL("/", request.nextUrl.origin));
  }
  return NextResponse.next();
}

export const config = {
  matcher: "/auth/:path*",
};

Next.js会自动加载所有匹配的中间件文件,各自独立生效。

内容的提问来源于stack exchange,提问作者l DraGSsine l

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 00:52:24