enctype="multipart/form-data"必须显式写在标签上且method为post,否则文件不会上传;写在上、用get提交、拼写错误或手动设置content-type头均导致失败。

enctype="multipart/form-data" 必须写在 <form></form> 标签上,不是 <input>
浏览器只认 <form enctype="multipart/form-data"></form> 这个声明,写在 <input type="file"> 上完全无效。常见错误是把属性加到 input 里,或者 JS 动态改 input.enctype,结果表单还是按默认 application/x-www-form-urlencoded 提交,后端 req.files 或 $_FILES 为空。
必须显式写出,不能依赖“浏览器自动识别”——HTML 不会因为页面里有 <input type="file"> 就自动切换编码。
-
<form method="post" enctype="multipart/form-data"></form>✅ 正确位置 -
<input type="file" enctype="multipart/form-data">❌ 完全被忽略 -
<form method="post"><input enctype="..."></form>❌ 属性没落在 form 上
method 必须是 post(或 put 等带 body 的方法)
enctype 在 method="get" 下直接失效。GET 没请求体,浏览器会静默丢弃文件字段,只把文本字段拼进 URL,input[type="file"] 的 value 变成空字符串或 C:\fakepath\... 这种伪路径。
不写 method 属性时,默认就是 get,所以漏写等于错写。
-
<form enctype="multipart/form-data"></form>❌ 默认 method=get,enctype 被忽略 -
<form method="post" enctype="multipart/form-data"></form>✅ 显式声明才生效 -
<form method="put" enctype="multipart/form-data"></form>✅ PUT 也支持(需后端路由匹配)
用 fetch + FormData 时,enctype 属性本身不起作用
只要用了 fetch 或 XMLHttpRequest 手动提交,<form enctype></form> 就只是个摆设。起作用的是你构造的 FormData 实例和请求配置。
浏览器在调用 fetch(url, { method: 'POST', body: new FormData(form) }) 时,会自动设置 Content-Type: multipart/form-data; boundary=...。手动加 headers: { 'Content-Type': ... } 反而会破坏 boundary 插入,导致后端解析失败。
- ✅ 正确:
fetch('/upload', { method: 'POST', body: new FormData(form) }) - ❌ 错误:
fetch('/upload', { headers: { 'Content-Type': 'multipart/form-data' }, body: new FormData(form) }) - ❌ 错误:
fetch('/upload', { method: 'POST', body: JSON.stringify(data) })—— 文件变字符串[object File]
大小写、拼写、空格一个都不能错
虽然 HTML 不区分大小写,但 multipart/form-data 是固定字符串,拼错或格式不对会导致后端收不到文件。
Chrome DevTools → Network → 查请求 Headers → 看 Content-Type 是否以 multipart/form-data; boundary= 开头。如果不是,说明前端根本没走对路径。
- ❌
MULTIPART/FORM-DATA(全大写易被误判为错误) - ❌
mutlipart/form-data(少个i) - ❌
multipart/ form-data(中间空格) - ✅ 统一小写:
multipart/form-data
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











