Next-Auth本地正常Vercel部署登录报错:JSON输入意外结束
Next.js 13.4 + NextAuth 部署Vercel后登录报错
SyntaxError: Unexpected end of JSON input解决方案 问题背景
使用Next.js 13.4(App Router)+ NextAuth 4.22.1开发的项目,本地登录功能正常,但部署到Vercel后所有登录尝试均跳转至错误页,Vercel日志显示SyntaxError: Unexpected end of JSON input,错误来自api/login接口的JSON解析步骤,凭证在前端传输正常但Vercel端接收时丢失。
排查与解决方案
1. 修正App Router API路由的请求体读取方式
App Router的API路由逻辑与Pages Router不同,需确保正确读取请求体:
- 替换Pages Router风格的
req.body,改用await request.json()读取请求体; - 避免多次读取请求体(请求体为可读流,仅能读取一次)。
示例代码(app/api/login/route.js):
export async function POST(request) { try { // 正确读取请求体 const credentials = await request.json(); // 后续认证逻辑 return Response.json({ success: true }); } catch (err) { console.error("Request parse error:", err); return Response.json({ error: "Invalid request" }, { status: 400 }); } }
2. 检查NextAuth配置的正确性
在app/api/auth/[...nextauth]/route.js中确认以下配置:
- 确保
secret正确引用process.env.NEXTAUTH_SECRET; - 若使用自定义登录页,
pages.signIn需指向正确路径; - 回调函数中无未处理的错误或错误重定向。
示例配置:
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; export const authOptions = { providers: [ CredentialsProvider({ name: "Credentials", credentials: {}, async authorize(credentials) { // 你的认证逻辑 const { username, password } = credentials; // 验证用户信息 if (username === "test" && password === "test") { return { id: "1", name: "Test User" }; } return null; }, }), ], secret: process.env.NEXTAUTH_SECRET, session: { strategy: "jwt" }, pages: { signIn: "/" }, // 根据实际登录页路径调整 }; export default NextAuth(authOptions);
3. 验证Vercel环境变量配置
- 确认
NEXTAUTH_URL为部署后的完整域名(如https://jinmatestapi.vercel.app),包含https://且无多余字符; - 重新在Vercel控制台(项目设置→环境变量)输入并保存环境变量,随后触发重新部署。
4. 确保请求头与CORS配置正确
- 前端发送登录请求时,需设置
Content-Type: application/json请求头,避免Vercel无法解析请求体; - 若需配置CORS,在API路由中添加响应头:
export async function POST(request) { // 处理逻辑... return new Response(JSON.stringify(result), { headers: { "Content-Type": "application/json", "Access-Control-Allow-Origin": process.env.NEXTAUTH_URL, // 限制来源更安全 }, }); }
5. 调试请求体传输
在api/login接口中添加日志,确认Vercel端实际接收的请求体内容:
export async function POST(request) { const rawBody = await request.text(); console.log("Raw received body:", rawBody); try { const credentials = JSON.parse(rawBody); console.log("Parsed credentials:", credentials); } catch (err) { console.error("JSON parse error:", err); } // 后续逻辑 }
通过Vercel日志查看输出,判断是请求体为空还是格式错误,再针对性修复。
内容的提问来源于stack exchange,提问作者Brett Williams
相关产品推荐
相关产品推荐

