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

Next.js@13+搭配Turbopack时middleware.ts位置及执行异常问题

问题

我用Turbopack创建了Next.js@13.0.5项目,在项目根目录添加了middleware.ts文件,但发送请求(比如/api/search?query=Hello)时中间件没执行。想知道最新版Next.js里middleware.ts的正确位置,我的中间件代码如下:

import { NextRequest } from 'next/server';
import { query } from 'express-validator';
import validateRequest from '@/lib/request-validation';

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

  if (
    request.method === 'GET' &&
    request.nextUrl.pathname.startsWith('/search')
  ) {
    const res = validateRequest([
      query('query').isString(),
      query('page').isNumeric(),
      query('perPage').isNumeric(),
    ]);

    return res;
  }
}
解答

一、middleware.ts的正确位置

在Next.js 13+(含13.0.5)中,middleware.ts(或.js)的正确位置是项目根目录,或者src目录的根层级(如果项目采用src目录结构)。你当前放置的位置是符合要求的,中间件未执行是由其他问题导致。

二、代码中的关键问题

  1. 路径匹配错误:你的请求路径是/api/search,但代码里判断的是pathname.startsWith('/search'),实际路径不满足该条件,导致中间件逻辑无法触发。需要修改为startsWith('/api/search')。
  2. 依赖不兼容Edge Runtime:Next.js的Middleware运行在Edge Runtime环境,而express-validator是为Express框架设计的,依赖Node.js特定API,无法在Edge环境正常工作,会导致验证逻辑失效甚至报错。
  3. 缺少匹配规则配置:建议添加config.matcher明确指定中间件要匹配的路径,确保目标请求被正确覆盖,同时避免不必要的路径触发中间件。

三、修正后的示例代码

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

// 适配Edge Runtime的自定义验证逻辑
function validateSearchParams(request: NextRequest) {
  const { searchParams } = request.nextUrl;
  const query = searchParams.get('query');
  const page = searchParams.get('page');
  const perPage = searchParams.get('perPage');

  if (!query || typeof query !== 'string') {
    return NextResponse.json({ error: 'query必须是字符串' }, { status: 400 });
  }
  if (page && isNaN(Number(page))) {
    return NextResponse.json({ error: 'page必须是数字' }, { status: 400 });
  }
  if (perPage && isNaN(Number(perPage))) {
    return NextResponse.json({ error: 'perPage必须是数字' }, { status: 400 });
  }
  return null;
}

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

  if (request.method === 'GET' && request.nextUrl.pathname.startsWith('/api/search')) {
    const validationError = validateSearchParams(request);
    if (validationError) {
      return validationError;
    }
  }
}

// 指定中间件匹配的路径
export const config = {
  matcher: '/api/search/:path*',
};

内容的提问来源于stack exchange,提问作者tronx.dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:35:10