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

React与Next.js中FormData提交表单数据异常问题排查

问题根因
  • 自定义Input组件内的原生<input>标签未绑定name属性。FormData遵循原生HTML表单的收集规则,只会收录携带合法name属性的表单控件值,你虽然将name参数传给了自定义组件,但组件渲染真实DOM输入框时没有透传该属性,所有字段对FormData来说都是无名字段,不会被采集。
  • 自定义Input中给原生输入框绑定了value={input},但父组件调用Input时从未传入input参数,也没有配套的onChange事件同步输入值。这会让输入框进入异常的半受控状态:用户输入的内容无法正常同步到DOM节点的value属性,甚至会出现输入无响应的情况,FormData自然读不到有效值。
  • 客户端调试方式有误:FormData是浏览器提供的特殊接口实例,不是普通JavaScript对象,直接console.log(fd)只会打印空的对象结构,无法看到内部存储的键值对,必须通过get()、entries()等实例方法才能读取内容。
  • 服务端解析逻辑不匹配:Next.js API路由默认的body解析器仅支持application/json、application/x-www-form-urlencoded两种请求格式,无法自动解析multipart/form-data类型的FormData载荷,因此直接打印req.body只会看到表单分隔符字符串,拿不到实际字段。
修复方案
  1. 修正自定义Input组件,透传name属性,移除多余的受控value绑定,补全属性默认值:
export default function Input({ name, type = "text", placeholder, pattern, required }) {
    return (
        <label className="input-group input-group-vertical">
            <span className="select-none">{required ? '*' + name : name}</span>
            <input 
                name={name}
                type={type} 
                className="input input-bordered" 
                pattern={pattern}
                placeholder={placeholder} 
                required={required} 
            />
        </label>
    )
}
  1. 修正客户端FormData调试逻辑,验证字段采集结果:
const handleSubmit = async (e) => {
    e.preventDefault();
    const fd = new FormData(e.target)
    // 遍历打印所有采集到的字段,用于调试
    for (const [key, value] of fd.entries()) {
        console.log(key, value)
    }
    const res = await fetch('/api/admin/add', {
        method: 'POST',
        body: fd
    }).then(res => res.json())
    console.log(res)
}
  1. 调整Next.js API路由配置,适配FormData格式请求:
    首先关闭默认的bodyParser避免干扰multipart格式解析,再手动读取请求内容:
// 关闭路由默认的body解析
export const config = {
  api: {
    bodyParser: false,
  },
}

export default async function AddHosp(req, res){
    // 读取请求流内容
    const chunks = []
    for await (const chunk of req) {
        chunks.push(chunk)
    }
    const rawFormData = Buffer.concat(chunks).toString()
    console.log(rawFormData)
    // 生产环境处理FormData建议引入formidable等成熟解析库,尤其是涉及文件上传的场景
    // 纯文本场景也可以在客户端将FormData转成普通对象后用JSON格式发送,适配默认解析逻辑
    return res.status(200).json({
        msg: 'request success'
    })
}

补充说明:如果不需要上传文件,更简便的方式是在客户端提交前用Object.fromEntries(fd)把FormData转成普通对象,设置Content-Type: application/json后发送,服务端无需修改配置即可通过req.body直接拿到解析后的字段,适配成本更低。

内容的提问来源于stack exchange,提问作者prithvi2k2

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:33:11