FormData不能直接转JSON,需用Object.fromEntries()处理文本字段;同名字段用getAll()转数组;文件字段不可序列化,应跳过或存元信息;name属性不能为空且控件不能disabled。

form元素直接用FormData拿不到JSON
浏览器原生的 FormData 对象不是 JSON,它内部是键值对集合(支持重复键、文件 Blob),不能直接 JSON.stringify()。强行转只会得到空对象 {} 或报错。常见错误是写成:
JSON.stringify(new FormData(form))——这毫无意义。
用Object.fromEntries()快速转基础表单字段
适用于纯文本输入(<input type="text">、<select>、<textarea>等),不包含文件或同名多值字段:
- 先调用
new FormData(form).entries()得到迭代器 - 再用
Object.fromEntries()转成普通对象 - 最后
JSON.stringify()即可
示例代码:
const form = document.querySelector('form');<br>const data = Object.fromEntries(new FormData(form));<br>const json = JSON.stringify(data);
处理复选框、多选下拉、同名字段要用getAll()
当存在多个同名控件(如 <input type="checkbox" name="tag"> 多个)时,FormData.get() 只返回第一个值,必须用 getAll() 手动收集:
立即学习“前端免费学习笔记(深入)”;
-
formData.getAll('tag')返回字符串数组(即使只选一个,也是['a']) - 需遍历所有字段名,用
formData.keys()去重获取唯一键名 - 对每个键判断:若
formData.getAll(key).length > 1,就用数组;否则取formData.get(key)
简单实现逻辑:
const obj = {};<br>for (const key of formData.keys()) {<br> const values = formData.getAll(key);<br> obj[key] = values.length === 1 ? values[0] : values;<br>}
文件字段不能直接进JSON,得单独处理
<input type="file"> 的值是 File 对象,无法序列化进 JSON。如果需要上传,应保持 FormData 原样提交;如果只是“模拟”结构,可存文件名或占位信息:
- 检测字段是否为
File:formData.get(key) instanceof File - 安全做法是跳过该字段,或显式设为
null/{ name: file.name, size: file.size } - 不要尝试
readAsDataURL塞进 JSON——大文件会撑爆内存,且破坏原始二进制语义
真正要发文件,别转 JSON,直接 fetch(url, { method: 'POST', body: formData })。
最易被忽略的是:表单控件的 name 属性必须存在且非空,否则 FormData 根本不会收录它;另外禁用(disabled)字段也不会被采集——这两点不检查,JSON 看起来就“丢数据”。



















