FormData.append()传文件无效主因是未正确传入File对象或字段名不匹配,且fetch上传时手动设置Content-Type会破坏boundary导致后端收不到文件,必须由浏览器自动设置。

FormData.append() 传文件时为什么没效果
常见原因是直接传 File 对象但没指定字段名,或误传了 input.files[0].name 字符串而非文件对象本身。浏览器会静默忽略非法参数,控制台也不报错。
- 必须用
input[type="file"].files[0](File实例)作为第二个参数,不能是路径字符串或input.value - 第一个参数(字段名)要和后端约定一致,比如后端 expect
avatar,就写formData.append("avatar", file) - 如果选了多个文件,需循环调用
append(),或用相同字段名多次添加(如formData.append("files", file1); formData.append("files", file2))
fetch 上传 FormData 必须禁用 Content-Type
手动设置 Content-Type 会导致浏览器无法自动插入 boundary,服务端收不到文件。这是最常踩的坑。
- 完全不要在
headers中设Content-Type——fetch会自动设为multipart/form-data; boundary=... - 错误写法:
fetch("/upload", { method: "POST", headers: { "Content-Type": "multipart/form-data" }, // ❌ 删掉这行 body: formData }); - 正确写法:
fetch("/upload", { method: "POST", body: formData // ✅ 让浏览器自动处理 headers });
XMLHttpRequest 和 fetch 在 FormData 上传中的关键差异
两者都支持,但错误处理和进度监听方式不同,影响调试效率。
-
XMLHttpRequest可用upload.onprogress监听上传进度,fetch原生不支持(需用ReadableStream+TransformStream拦截,复杂度高) -
fetch默认不带 cookie,如需认证,得加credentials: "include" -
XMLHttpRequest的responseType = "json"会自动解析,fetch需手动调res.json()
后端接收不到文件?先检查 enctype 和 input 属性
前端漏掉关键属性,表单会退化为普通文本提交,FormData 也救不了。
立即学习“前端免费学习笔记(深入)”;
-
不需要enctype(FormData不依赖它),但若混用原生表单提交,必须设enctype="multipart/form-data" -
必须有name属性,否则input.files虽可读取,但FormData构造时无法关联字段名 - 多文件上传要加
multiple属性:











