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目录结构)。你当前放置的位置是符合要求的,中间件未执行是由其他问题导致。
二、代码中的关键问题
- 路径匹配错误:你的请求路径是
/api/search,但代码里判断的是pathname.startsWith('/search'),实际路径不满足该条件,导致中间件逻辑无法触发。需要修改为startsWith('/api/search')。 - 依赖不兼容Edge Runtime:Next.js的Middleware运行在Edge Runtime环境,而
express-validator是为Express框架设计的,依赖Node.js特定API,无法在Edge环境正常工作,会导致验证逻辑失效甚至报错。 - 缺少匹配规则配置:建议添加
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
相关产品推荐
相关产品推荐

