必须设为 multipart/form-data,否则前端根本不会发送文件;浏览器默认用 application/x-www-form-urlencoded 编码,会丢弃文件二进制内容,仅 multipart/form-data 能正确分块传输文件。

必须设为 multipart/form-data,否则文件根本不会发出——不是后端收不到,是前端压根没发。
为什么 enctype="multipart/form-data" 不可省略
浏览器默认用 application/x-www-form-urlencoded 编码表单,它会把所有字段转成 a=1&b=hello%20world 这类字符串。遇到 <input type="file">,它只传个空值或 C:\fakepath\abc.jpg 这种路径字符串,二进制内容直接丢弃。
multipart/form-data 是唯一能让浏览器把文件切分成带 Content-Disposition 和真实 Content-Type 的二进制块(part)的编码方式,中间用随机 boundary 分隔。没有它,HTTP 请求体里连 boundary= 都看不到。
- 漏写或拼错(如
mutlipart/form-data)→ 后端req.files或request.FILES为空 - 写在
<input>上(如<input enctype="">)→ 完全无效 - 用 GET 提交 → 浏览器静默忽略
enctype,文件字段被丢弃
enctype 必须写在 <form></form> 标签上,且大小写要对
它只作用于整个表单,不能继承、不能动态补加、不能靠 JS 提交时“事后弥补”。HTML 不区分大小写,但写成 MULTIPART/FORM-DATA 容易被误读为拼写错误,统一小写最稳妥。
- ✅ 正确:
<form action="/upload" method="post" enctype="multipart/form-data"></form> - ❌ 错误:
<form enctype="MUTIPART/FORM-DATA"></form>(大小写混乱) - ❌ 错误:
<form><input enctype="multipart/form-data"></form>(属性位置错)
动态创建表单时:const form = document.createElement('form'); form.enctype = 'multipart/form-data';,不设就还是默认编码。
用 fetch + FormData 时,enctype 属性其实不生效
原生表单提交才看 <form enctype></form>;用 JS 手动发请求时,起作用的是你构造的数据对象。只要用了 new FormData(formElement) 或 FormData.append('file', input.files[0]),浏览器会自动设置 Content-Type: multipart/form-data; boundary=...。
- ✅ 正确:
fetch('/upload', { method: 'POST', body: new FormData(form) }) - ❌ 错误:
fetch('/upload', { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) })→ 文件变[object File] - ❌ 错误:手动设
headers: { 'Content-Type': 'multipart/form-data' }→ 丢失boundary,后端解析失败 - ⚠️
FormData.append()第二个参数必须是File实例,不是input.value(那是只读路径字符串)
真正容易被忽略的是:enctype 是表单级开关,一旦没配对,整个上传链路在第一环就断了——你查后端日志、抓包、甚至重写路由都没用,因为请求体里根本没有文件数据。别在后端兜圈子,先盯住这个属性是否出现在正确的标签和拼写上。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











