必须设为multipart/form-data且method为POST,否则浏览器不发送文件二进制内容;默认application/x-www-form-urlencoded仅传文件路径字符串,multipart/form-data才生成含boundary分隔的二进制块。

必须把 form 标签的 enctype 属性设为 multipart/form-data,同时 method 必须是 post(或其它带请求体的方法,如 put),缺一不可。
enctype="multipart/form-data" 是唯一有效值
浏览器默认用 application/x-www-form-urlencoded 编码表单,它会把所有字段转成类似 a=1&b=hello 的字符串。遇到 <input type="file">,只会传个空值或假路径(如 C:\fakepath\abc.jpg),真实二进制内容直接丢弃。
multipart/form-data 才能让浏览器把文件切分成带头信息(Content-Disposition、Content-Type)的二进制块,中间用随机 boundary 分隔。没有它,HTTP 请求体里连 boundary= 都看不到。
- 写错大小写(如
MUTIPART/FORM-DATA)→ 后端收不到文件 - 拼写错误(如
mutlipart/form-data)→ 等同于没设 - 写在
<input>上(如<input enctype="">)→ 完全无效 - 用 GET 提交 → 浏览器静默忽略 enctype,文件字段被丢弃
method 不能是 GET
GET 请求没有请求体(body),而 multipart/form-data 必须靠 body 传输分块数据。即使你写了 enctype="multipart/form-data",只要 method="get",浏览器就自动退回到默认编码,文件根本不会发出。
立即学习“前端免费学习笔记(深入)”;
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
哪怕你在 URL 后手动拼了 ?file=test.jpg,也只传了个文件名字符串,不是文件内容。
- 必须用
method="post"或method="put"等支持 body 的方法 - 表单里只要有一个
type="file"字段,整个表单就必须满足这两项条件 - 别信“兼容写法”——
enctype不支持多个值,也不接受空格或逗号分隔
动态创建或 JS 提交时要注意
原生表单提交才看 <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) }) - ❌ 错误:
headers: { 'Content-Type': 'application/json' }→ 文件变[object File] - ❌ 错误:手动设
'Content-Type': 'multipart/form-data'→ 丢失 boundary,后端解析失败 - 动态创建表单时:
form.enctype = 'multipart/form-data'必须显式设置,否则仍是默认编码
怎么验证是否生效
上传失败时,错误往往藏在请求细节里,而不是控制台红字。
- Chrome DevTools → Network → 点开请求 → Headers → 查看
Content-Type是否为multipart/form-data; boundary=... - 如果不是,说明
enctype没生效,或被 JS 覆盖 - 服务端日志出现
Invalid boundary in multipart→ 大概率是前端手动设了Content-Type却没删掉浏览器自动生成的 boundary - 后端读文件时字段名大小写敏感,
<input name="Avatar">和request.files.get('avatar')对不上


















