如何在Next.js 13的middleware.ts中修改请求体?
在Next.js 13中间件中修改请求体的正确方式
你遇到的错误是因为NextRequest的body属性是只读的,无法直接赋值修改。要在中间件里修改请求体,必须创建一个新的Request实例来重构请求,再通过NextResponse.rewrite转发这个修改后的请求。
修改后的完整代码
import { NextRequest, NextResponse } from 'next/server'; enum MiddlewareRoutes { ACCESS = '/api/access', } const middlewareHandler = async ( route: MiddlewareRoutes, response: NextResponse ): Promise<NextResponse> => { switch (route) { case MiddlewareRoutes.ACCESS: { response.cookies.set({ name: 'vercel', value: 'fast', path: '/', }); return response; } default: { return response; } } }; export async function middleware(request: NextRequest) { // 构造新的请求体,若需基于原请求体修改,可先通过await request.json()读取原内容 const newBody = JSON.stringify({ hello: 'world' }); // 创建新的Request实例,保留原请求的关键上下文信息 const modifiedRequest = new Request(request.url, { method: request.method, headers: new Headers(request.headers), body: newBody, credentials: request.credentials, }); // 设置自定义请求头 modifiedRequest.headers.set('ABC', 'DEG'); // 转发修改后的请求并获取响应 let response = NextResponse.rewrite(modifiedRequest); // 执行原有响应处理逻辑 response = await middlewareHandler( (request.nextUrl.pathname ?? '') as MiddlewareRoutes, response ); return response; } export const config = { matcher: ['/api/:path*'], };
关键说明
- 不可直接修改原请求:
NextRequest是不可变对象,所有核心属性(包括body)都无法直接赋值修改,必须通过新实例重构请求。 - 保留请求上下文:创建新
Request时,要复制原请求的method、url、headers、credentials等信息,避免破坏原有请求的认证、方法等逻辑。 - 请求体序列化:如果是JSON格式的请求体,必须先转成字符串(
JSON.stringify),否则后端无法正确解析内容。 - 响应仍可修改:
NextResponse.rewrite返回的响应对象仍支持后续修改(比如设置Cookie、添加响应头),不影响原有业务逻辑。
内容的提问来源于stack exchange,提问作者Shivam Sahil
相关产品推荐
相关产品推荐

