enctype="multipart/form-data"是文件上传的硬性前提,必须显式设在标签上且method为post,否则浏览器不打包二进制内容;拼写错误、位置错误或使用get均导致文件字段被静默丢弃。

必须设为 multipart/form-data,否则文件根本不会发出——不是后端收不到,是浏览器压根不打包二进制内容。
enctype 必须写在 <form></form> 标签上,且大小写要对
这个属性只作用于整个表单,不能写在 <input> 或 <button></button> 上,也不能靠 JS “事后补”。常见错误包括:
-
enctype="MUTIPART/FORM-DATA"(拼错或大小写混乱)→ 浏览器当无效值处理,回退到默认编码 -
<form><input enctype="multipart/form-data"></form>(位置错)→ 完全无效果 - 动态创建表单时没设:
const form = document.createElement('form'); form.enctype = 'multipart/form-data';→ 不设就还是application/x-www-form-urlencoded
method 不能是 GET,必须是 POST(或 PUT 等带 body 的方法)
enctype="multipart/form-data" 依赖 HTTP 请求体(body)来组织分块数据,而 GET 请求没有 body。浏览器遇到 <form method="get" enctype="multipart/form-data"></form> 会直接忽略 enctype,退回到默认编码,<input type="file"> 字段被静默丢弃。
- 哪怕你手动拼 URL 参数如
?file=test.jpg,传的也只是字符串,不是文件内容 - 某些旧文档提“GET 可上传小文件”,纯属误解;HTTP 协议层面就不支持
用 fetch + FormData 时,enctype 属性本身不生效
原生表单提交才看 <form enctype></form>;JS 手动发请求时,起作用的是你构造的数据对象。只要用了 new FormData(formElement),浏览器会自动设置正确的 Content-Type: multipart/form-data; boundary=...。
- ✅ 正确:
fetch('/upload', { method: 'POST', body: new FormData(form) }) - ❌ 错误:
headers: { 'Content-Type': 'application/json' }+JSON.stringify(data)→ 文件变[object File] - ❌ 错误:
headers: { 'Content-Type': 'multipart/form-data' }→ 缺少boundary,后端解析失败 - ⚠️
FormData.append()第二个参数必须是File实例,不是input.value(那是只读路径字符串)
后端收不到字段?先确认 Content-Type 是否含 boundary=
Chrome DevTools → Network → 点开请求 → Headers → 查看 Content-Type 字段。如果它不是形如 multipart/form-data; boundary=----WebKitFormBoundary...,说明前端没生效,别急着改后端。
- 服务端日志出现
Invalid boundary in multipart→ 大概率是前端手动设置了Content-Type但没删掉浏览器自动生成的boundary - 后端只收到文件、收不到文本字段 → 不是前端漏传,是后端没调用框架专用接口(如 Flask 的
request.form.get()和request.files.get()分开取) - 字段名大小写敏感:
<input name="Avatar">对应后端request.files.get('Avatar'),写成'avatar'就为空
最常被忽略的一点:只要表单里有任何一个 <input type="file">,整个表单就必须用 multipart/form-data,哪怕其他全是文本字段——没有例外,也没有“兼容写法”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











