NextJS Pages Router转App Router后联系表单字段为空问题
NextJS App Router联系表单字段返回null的解决方案
核心问题原因
Pages Router与App Router的API请求体解析逻辑存在差异:
- Pages Router直接通过
req.body获取已解析的请求体 - App Router需要通过异步的
request.json()方法解析请求体,未正确处理会导致请求体为undefined,触发TypeError;服务端返回500错误时若未输出有效JSON,客户端会出现JSON解析失败的报错。
分步修复方案
1. 修正API路由(src/app/api/contactForm/route.ts)
替换原路由代码,确保异步解析请求体并处理错误:
import { NextResponse } from 'next/server'; export async function POST(request: Request) { try { // 关键:App Router必须异步解析请求体 const body = await request.json(); const { firstName, email, message } = body; // 必填字段验证(可根据业务需求调整) if (!firstName || !email || !message) { return NextResponse.json({ error: '所有字段均为必填项' }, { status: 400 }); } // 执行你的业务逻辑(如发送邮件、存储数据等) // ... return NextResponse.json({ success: true }, { status: 200 }); } catch (error) { console.error('表单处理错误:', error); // 确保返回有效JSON,避免客户端解析失败 return NextResponse.json({ error: '服务器内部错误' }, { status: 500 }); } }
2. 修复客户端提交逻辑(useContactForm.ts)
确保请求头正确设置,并先判断响应状态再解析JSON:
export async function submitContactForm(formData: { firstName: string; email: string; message: string }) { try { const response = await fetch('/api/contactForm', { method: 'POST', headers: { 'Content-Type': 'application/json', // 必须设置该头,服务端才能正确解析JSON }, body: JSON.stringify(formData), }); // 先判断响应状态,再处理响应内容 if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || '表单提交失败'); } return await response.json(); } catch (error) { console.error('提交错误:', error); throw error; } }
3. 确保表单组件为客户端组件
表单交互逻辑必须放在客户端组件中,添加'use client'指令:
// src/app/components/ContactForm.tsx 'use client'; import { useState } from 'react'; import { submitContactForm } from '../hooks/useContactForm'; export default function ContactForm() { const [formData, setFormData] = useState({ firstName: '', email: '', message: '' }); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); try { await submitContactForm(formData); alert('提交成功!'); setFormData({ firstName: '', email: '', message: '' }); } catch (error) { alert((error as Error).message); } }; return ( <form onSubmit={handleSubmit}> <input type="text" value={formData.firstName} onChange={(e) => setFormData({ ...formData, firstName: e.target.value })} placeholder="姓名" required /> <input type="email" value={formData.email} onChange={(e) => setFormData({ ...formData, email: e.target.value })} placeholder="邮箱" required /> <textarea value={formData.message} onChange={(e) => setFormData({ ...formData, message: e.target.value })} placeholder="留言" required /> <button type="submit">提交</button> </form> ); }
错误对应说明
- 终端
TypeError: Cannot read properties of undefined (reading 'firstName'):服务端未异步解析请求体,body为undefined,解构字段时报错。 - 控制台
Unexpected end of JSON input:服务端500错误时未返回有效JSON响应,客户端response.json()解析空内容失败。
内容的提问来源于stack exchange,提问作者C. Outwin
相关产品推荐
相关产品推荐

