Next.js中间件使用可选链后req对象被意外修改的问题求助
问题原因与解决方案
核心原因
你遇到的问题和Next.js的API请求对象特性、next-connect的中间件执行机制直接相关:
- Next.js API路由中的
req并非原生Node.jsIncomingMessage,而是Next.js封装的NextApiRequest对象,它的处理逻辑和普通CLI环境的req完全不同。 - 最可能的触发点是你的中间件错误地返回了
req.headers.authorization的原始值——next-connect的规则是:如果中间件返回了非undefined的内容,会直接终止整个中间件链,并将返回值作为响应内容返回。这会让你误以为req对象被篡改,实际上是中间件提前结束并输出了那个值。
修复步骤
- 检查中间件的返回逻辑:确保你的中间件只修改req对象,绝对不要return任何值,必须调用
next()来传递控制权给后续中间件。 - 正确的中间件示例:
import { createRouter } from 'next-connect'; import type { NextApiRequest, NextApiResponse } from 'next'; // 扩展NextApiRequest类型,添加jwt属性(TypeScript可选) declare module 'next' { interface NextApiRequest { jwt?: string; } } const router = createRouter<NextApiRequest, NextApiResponse>(); // Token提取中间件 router.use((req, res, next) => { const authHeader = req.headers.authorization; // 用可选链和前缀校验提取Token if (authHeader?.startsWith('Bearer ')) { req.jwt = authHeader.slice(7); } // 必须调用next,不能return任何内容 next(); }); // 后续JWT解析中间件 router.use((req, res, next) => { if (req.jwt) { // 这里执行JWT解析逻辑 // 比如 verify(req.jwt, secret) } next(); }); export default router.handler();
为什么CLI测试正常?
普通Node.js CLI环境中没有框架级的中间件拦截逻辑,即使你不小心return了值,也只会影响函数返回结果,不会修改req对象或终止请求流程,所以测试时不会出现问题。
内容的提问来源于stack exchange,提问作者Ron
相关产品推荐
相关产品推荐

