Object.fromEntries 更可靠,因其原生匹配 FormData 迭代规范,不丢键、不误转类型、保留最后重复键;但多选 checkbox 需用 getAll 手动处理,File 字段经 JSON.stringify 会消失,故文件上传应直接提交 FormData。
Object.fromEntries 为什么比手动遍历更可靠因为 FormData 的 entries() 方法原生支持迭代键值对,而 Object.fromEntries 正是为此设计的——它不丢键、不误转布尔/数字、不忽略重复键(会保留最后一个),且能直接处理 File 对象(虽然转成 JSON 后需另行处理)。手动用 for...of 或 Array.from + reduce 容易漏掉 undefined 值或误把 File 当字符串序列化。
Object.fromEntries 转换后,File 字段会变成什么会变成 File 实例对象,但 JSON.stringify 时会被忽略(因为 File 不可枚举且无自有可序列化属性),导致字段“消失”。这不是 Object.fromEntries 的问题,而是 JSON 序列化限制:
const data = new FormData();data.append('avatar', new File([''], 'test.jpg', {type: 'image/jpeg'}));data.append('name', 'Alice');const obj = Object.fromEntries(data);console.log(obj.avatar); // File {name: "test.jpg", lastModified: ..., size: 0, type: "image/jpeg"}console.log(JSON.stringify(obj)); // {"name":"Alice"} ← avatar 消失了
fetch(url, { method: 'POST', body: formData })
FileReader 或 arrayBuffer() 提前转为 base64 / blob URL,再塞进对象input[type="text"]、select、textarea)可安全转换Object.fromEntries 遇到多选 checkbox 怎么办浏览器原生把同名 checkbox 多选值按顺序 append 多次,FormData.entries() 会返回多个相同键的条目,但 Object.fromEntries 只保留最后一个——这会导致只拿到最后一个勾选项。
FormData.getAll(key) 手动收集数组const hobbies = formData.getAll('hobby'); → 返回 ['reading', 'swimming']
{ ...Object.fromEntries(formData), hobby: formData.getAll('hobby') }
fromEntries
Object.fromEntries 在 IE 中完全不可用,但不需要引入整个 core-js。可以用一行 reduce 模拟:
const fromEntries = (iterable) => Array.from(iterable).reduce((obj, [k, v]) => ({ ...obj, [k]: v }), {});
@babel/preset-env 并设 targets.ie: "11" 会自动 polyfillObject.assign(...) 展开,容易被原型污染(比如 key 是 __proto__)FormData——混用两种提交方式时,字段命名冲突和类型隐式转换才是真坑。