Vercel Serverless函数JSON解析异常求助
req.json()解析失败问题 问题背景
在Next.js App Router的/api路由处理器中调用await req.json()时,Vercel Serverless函数抛出SyntaxError: Unexpected end of JSON input错误,但本地开发环境及其他部署平台均正常运行。路由日志显示artwork route hit!输出,但req.body检查和解析后的日志均未触发,怀疑是Vercel运行时或中间件配置问题。
排查与解决方案
1. 检查中间件是否消耗了请求体流
如果项目中的中间件调用了req.text()、req.json()等读取请求体的方法,会直接消耗请求体流,后续路由处理器无法再次读取。本地环境可能对请求体复用更宽松,但Vercel运行时严格遵循流的一次性读取规则。
解决方法:在中间件中克隆请求对象后再读取请求体:
// middleware.ts export async function middleware(req: NextRequest) { // 克隆请求以避免消耗原始请求体 const clonedReq = req.clone(); const body = await clonedReq.json(); // 中间件业务逻辑... return NextResponse.next(); }
2. 调整Vercel请求体大小限制
Vercel Serverless函数默认请求体大小限制为4.5MB,若请求体接近或超过该值,会被截断导致JSON解析不完整。
解决方法:在项目根目录创建/修改vercel.json,指定对应API路由的请求体大小限制:
{ "functions": { "app/api/**/*.{js,ts,jsx,tsx}": { "maxRequestBodySize": "10mb" } } }
3. 验证请求头Content-Length的准确性
客户端发送的Content-Length头若与实际请求体字节数不匹配,Vercel运行时会提前终止请求体读取,导致JSON不完整。
解决方法:确保客户端请求的Content-Length头准确对应请求体的实际字节数;若客户端支持,可改用Transfer-Encoding: chunked传输方式。
4. 添加调试日志定位请求体问题
在路由处理器中添加错误捕获和原始请求体打印,查看Vercel实际收到的请求内容:
export async function POST(req: NextRequest) { console.log("artwork route hit!"); try { // 读取原始请求体文本(注意不要打印敏感数据) const rawBody = await req.text(); console.log("Raw request body:", rawBody); // 手动解析JSON const job: Job = JSON.parse(rawBody); console.log(`new job parsed: ${job.id}`); // 后续业务逻辑... } catch (error) { console.error("JSON解析失败详情:", error); return new NextResponse("请求体格式错误", { status: 400 }); } }
部署后查看Vercel函数日志,确认请求体是否被截断或篡改。
5. 清除Vercel部署缓存
旧代码或配置可能因部署缓存残留导致问题,尝试重新部署并清除缓存:在Vercel控制台的部署页面,点击「Redeploy」并勾选「Clear build cache」。
内容的提问来源于stack exchange,提问作者Callum Kloos

