accept属性仅前端提示,无效于安全拦截;须用英文逗号分隔、补扩展名兜底、禁用无点格式;file.type不可信,应校验文件头魔数与大小;form需enctype="multipart/form-data";后端才是真实校验防线。

accept 属性只是前端提示,不能真正拦截非法文件。用户点“所有文件”就能绕过,后端必须用文件头(magic bytes)校验真实类型。
accept 属性怎么写才有效
它只影响文件选择对话框的默认过滤行为,不是安全机制。写法错误会导致完全失效:
- 必须用英文逗号分隔,不能加空格:
accept=".pdf,.docx,application/pdf"✅;accept=".pdf, .docx"❌ - MIME 类型优先(如
application/pdf),但 Windows 和移动端常误报,得补扩展名兜底(如.pdf) - 移动端 Safari 对 MIME 支持弱,
accept="image/*"不够稳,建议写成accept="image/jpeg,image/png,.jpg,.jpeg,.png" - 别写
accept="pdf,docx"—— 缺少点号会被浏览器忽略
JavaScript 校验 file.type 和 file.size 的坑
file.type 是浏览器猜的,不可信;file.size 倒是准确,但仅限大小检查:
-
file.type在拖拽上传或改过后缀时经常为空字符串,不能用来判断类型 - 取扩展名更可靠:
file.name.split('.').pop().toLowerCase(),但依然防不住恶意重命名(如hack.exe改成safe.jpg) - 大小检查用
file.size > 5 * 1024 * 1024(5MB),单位是字节,别错当成 KB - 校验后记得清空
input.value = '',否则重复触发 change 事件时files[0]还是旧文件
form 表单漏掉 enctype="multipart/form-data" 的后果
这是最隐蔽的失败点:表单看起来能选文件、能点提交,但后端收不到任何文件字段。
立即学习“前端免费学习笔记(深入)”;
- Express + multer 场景下,
req.file或req.files直接为undefined,控制台无报错,容易误判为 JS 问题 - PHP 中
$_FILES为空数组;Java Spring 中MultipartFile为 null - 必须同时满足:
method="post"+enctype="multipart/form-data",缺一不可 - 如果用了
multiple,后端接收字段名要匹配(如name="files[]"或name="attachments"),否则只拿到第一个
真正拦住危险文件的地方永远在服务端——读文件前 12 字节比对魔数,而不是看扩展名或 Content-Type 请求头。前端所有检查,只是让用户早点知道错了,别白等几秒上传完再被 400 打回。



















