跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

HTML中enctype multipart/form-data的使用场景与文件上传配置

enctype="multipart/form-data" 是文件上传的强制要求,必须显式设置在 form 标签上且 method 为 POST;其他编码格式无法传输二进制文件,accept 仅为前端提示,后端须校验 MIME 类型、魔数及文件大小等。 enctype="multipart/form-data" 是文件上传的强制要求,不是可选项 只要表单里有
,就必须在
标签上显式写
enctype="multipart/form-data"
,且
method
必须为
POST
。浏览器不会自动补全,也不接受默认值——设错或漏设,后端根本收不到文件对象(比如
req.file
或
request.files
为空)。 常见错误现象: 前端选了文件、点了提交,但后端日志里没打印出任何文件字段 用
application/json
提交,后端收到的是
[object File]
字符串 用
application/x-www-form-urlencoded
,文件内容被 URL 编码成乱码,原始字节丢失 原因很简单:
multipart/form-data
是唯一能携带原始二进制分块(含
Content-Disposition
和边界分隔符)的编码格式;其他类型压根不支持二进制边界结构。 form 标签上写 enctype,不是 input 或 button 上
enctype
属于
的属性,只对整个表单生效。它不会因为某个
input
是
type="file"
就自动触发,也不会继承自父级或通过 JS 动态添加后“追加生效”——必须在 HTML 渲染时就存在。 立即学习 “ 前端免费学习笔记(深入) ”; 实操建议: 检查源码,确认
这一行完整存在 不要写成
,这毫无意义 如果用 JavaScript 动态创建表单,记得在
appendChild
前给
form
元素设置
enctype
属性:
form.enctype = "multipart/form-data"
使用
fetch
+
FormData
时不用手动设
enctype
,浏览器会自动加请求头
Content-Type: multipart/form-data; boundary=...
accept 属性只是客户端提示,不能替代后端校验
能在部分浏览器中过滤文件类型选择弹窗,但它完全可被绕过:用户可以手动修改 HTML、用 curl 提交、或拖拽非允许类型文件。所以它只影响体验,不提供安全保证。 使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件 如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Andr​​oid友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Andr​​oid应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更 下载 真正起作用的只有后端: 检查
Content-Type
头(如
image/jpeg
),而非仅靠扩展名 读取文件魔数(magic bytes),比如 PNG 文件开头是
89 50 4E 47
限制总请求体大小(如 Node.js 的
multer.limits.fileSize
,Flask 的
MAX_CONTENT_LENGTH
) 重命名文件(避免
../../etc/passwd
类路径遍历),用
secure_filename()
或等效函数处理原始名 不校验 MIME 或魔数,单靠
accept
或后缀名白名单,很容易被传入伪装的 WebShell 文件。 FormData 对象内部已隐式使用 multipart/form-data 当用 JavaScript 构造
FormData
并 append 文件时,例如:
const fd = new FormData(); fd.append("avatar", fileInput.files[0]); fetch("/upload", { method: "POST", body: fd });
浏览器会自动以
multipart/form-data
编码发送,且生成合法的 boundary。你不需要、也不能手动设置
Content-Type
请求头——一旦显式设置了,浏览器反而会禁用自动 multipart 封装,导致服务端解析失败。 容易踩的坑: 写了
headers: { "Content-Type": "multipart/form-data" }
→ 错误,会丢掉 boundary,后端收不到文件 把
fileInput.files[0]
转成 blob 再 append → 没问题,
FormData
仍能正确封装 append 普通字符串字段(如
fd.append("name", "Alice")
)→ 它会和文件一起打包进同一个 multipart 请求,服务端可同时拿到文本和二进制 边界(boundary)是随机生成的,每次请求都不同,服务端解析器(如 multer、Django 的
request.FILES
)依赖它来切分各个 part —— 这个细节前端不用管,但得知道它真实存在且不可省略。

相关文章