必须显式设置enctype="multipart/form-data"且method="post",否则浏览器不发送文件二进制内容,后端req.files、$_files等均为空;默认application/x-www-form-urlencoded仅传路径字符串,不支持文件上传。

必须显式写 enctype="multipart/form-data",否则后端收不到任何文件数据——这不是可选项,是协议级硬性要求。
form 标签的 enctype 和 method 属性不能省
浏览器只认 form 标签上明写的 enctype="multipart/form-data",漏掉或写成 application/x-www-form-urlencoded(默认值)会导致:req.files 为空、$_FILES 为空、request.files 为空,连日志都看不到文件字段。
-
method必须为POST(或PUT等带 body 的方法),GET下input[type="file"]直接失效 - 不要试图用 JS 动态设置
form.enctype = "multipart/form-data"——它不触发浏览器重解析,无效 - 用
curl -d模拟提交时,根本构造不出合法 multipart 请求体;必须用curl -F
input type="file" 的 multiple 和 accept 要按规范写
multiple 必须显式出现在 HTML 中:<input type="file" multiple> 才生效;input.multiple = true 或 setAttribute('multiple', '') 在所有主流浏览器中均无效。
-
accept只影响文件选择弹窗的初始筛选视图(比如只显示图片),用户仍可手动切到“所有文件”并选任意类型——前端无法阻止 - 移动端尤其注意:iOS Safari 直到 16.4 才稳定支持
accept="application/pdf",对accept=".pdf,.docx"这类扩展名列表基本不识别 -
accept="image/*"在 Safari 和 Chrome 上表现一致,比列举 MIME 更可靠
name 属性决定后端怎么取文件
后端通过 name 值定位上传的文件:req.files['avatar'](Express + Multer)、$_FILES['avatar'](PHP)、request.files.getlist('documents')(Flask)。如果用了 multiple,name 必须统一,否则后端只拿到第一个。
- 单文件:
<input type="file" name="photo">→ 后端取req.file或req.files.photo[0] - 多文件:
<input type="file" name="files" multiple>→ 后端必须用数组方式接收,如req.files.files(Multer)或request.files.getlist('files')(Flask) - 别写
<input type="file" name="files[]">—— 这是 PHP 特有语法,其他后端不识别,且现代框架已不依赖此约定
Safari(尤其是 iOS)的兼容性现实
iOS Safari 至今不支持 webkitdirectory,也不支持可靠的多文件拖放;哪怕你把 HTML、JS、后端全写对了,用户在 iPhone 上点一次“选取文件”,仍然只能选一个。
- 这不是 bug,是 Apple 明确未实现的特性(截至 2026 年 9 月)
- 降级方案不是“优化项”,而是必选项:要么并排多个单文件
input,要么加文案提示“请使用桌面端上传多文件” - 不要用
DataTransfer构造预填充文件列表——Firefox 和 Safari 不支持,Chrome/Edge 也仅限本地测试环境
最常被忽略的点:所有这些属性都必须写在原始 HTML 中,运行时 JS 修改几乎全部无效;而 Safari 的限制不是“未来会支持”,是当前生态下必须绕开的客观事实。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











