accept属性仅提示浏览器过滤文件选择框,不能阻止非法上传;必须前后端协同:前端用accept+js校验扩展名和文件头,后端必须读取文件头(magic bytes)确认真实类型并重命名保存。

accept 属性只能提示浏览器过滤文件选择框里的可见类型,不能阻止用户上传非法文件。真要限制格式,必须前后端协同:前端用 accept + JS 校验做体验优化,后端必须读文件头(magic bytes)确认真实类型。
accept 属性怎么写才有效
它不是校验开关,只是 UI 提示。常见错误是只写扩展名不写 MIME,或空格分隔、大小写混用:
-
accept=".pdf,.docx"可行,但 Windows 下 .docx 常被报成application/vnd.openxmlformats-officedocument.wordprocessingml.document,漏掉就失效 - 优先用 MIME 类型:
accept="application/pdf,application/msword",再补扩展名兜底:accept=".pdf,application/pdf,.doc,application/msword" - 移动端 Safari 对 MIME 支持弱,
accept="image/*"不如accept="image/jpeg,image/png,.jpg,.png"稳定 - 多个值用英文逗号分隔,**不能有空格**:
accept=".jpg,.png,image/jpeg"✅,accept=".jpg, .png"❌
JS 检查文件类型和大小的坑
input.files[0].type 是浏览器推测的,不可信;.size 是准确的,但仅防大文件。关键逻辑得绕过 .type:
- 取扩展名更可靠:
file.name.split('.').pop().toLowerCase(),尤其拖拽上传时.type经常为空 - 检查大小用字节单位:
if (file.size > 5 * 1024 * 1024)(5MB),别写成> 5MB这种无效表达 - 别只判断
file.type === 'image/jpeg'—— 很多 JPG 文件返回空字符串或'' - JS 校验只用于提交前反馈,不能替代后端逻辑,否则改个后缀名(
hack.exe → safe.jpg)就全 bypass
form 提交失败的隐藏原因
如果后端收不到文件,第一反应不该是 JS 问题,先看表单基础配置:
-
<form></form>必须带enctype="multipart/form-data",缺了这个,req.file或request.files就是undefined或空对象 - 错误现象典型:
req.file is undefined(Express + multer)、$_FILES为空(PHP),但控制台没报错,容易卡在前端调试半天 -
<input type="file">必须有name属性,且和服务端接收字段名一致,比如后端用request.files['avatar'],那 input 就得是name="avatar" - 如果用了
multiple,后端收到的是数组,别当单个文件处理
真正拦住非法文件的地方永远在服务端——读文件前 12 字节比对魔数,不是看扩展名,也不是信 $_FILES['type'] 或 MultipartFile.getContentType()。前端所有限制,本质都是减少无效请求和提升反馈速度,不是安全边界。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











