You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 02:06:31