前端无法真正限制文件大小,只能在change事件中用file.size检查并清空input值;后端必须校验魔数、真实类型、服务器上传上限及文件名安全,且表单需正确配置enctype和method。

前端无法真正限制文件上传大小,accept 属性只管类型、不管体积;唯一能做的,是在用户选中文件后立刻用 file.size 检查并阻止提交——但这层检查完全可被绕过,后端必须重校一遍。
change 事件里读 file.size 是唯一有效时机
不能等到 submit 才检查,否则用户可能已选中 2GB 视频却毫无提示。必须监听 input[type="file"] 的 change 事件,在 e.target.files[0] 上取 size(单位字节)做判断:
- 检查前先确认
file存在且file.size有值,某些 iOS WebView 可能返回0 - 超过阈值时,必须手动清空
e.target.value = '',否则同名文件第二次选择不会触发change - 提示要直接给用户看,别只写
console.log——没人盯着控制台
用 data-max-size 实现每个 input 独立配置
避免硬编码,把限制值写进 HTML 属性更灵活:
- 在
input上加data-max-size="5242880"(即 5MB) - JS 里用
e.target.getAttribute('data-max-size')读取,转成数字后跟file.size比较 - 注意:属性值是字符串,不转
Number()或parseInt()会导致字符串比较出错
后端校验不是“补充”,而是强制要求
前端所有限制都形同虚设——用户禁用 JS、改后缀、伪造请求头,都能绕过。后端必须:
立即学习“前端免费学习笔记(深入)”;
- 解析文件头(魔数),而不是信
Content-Type或扩展名 - 用安全库识别真实类型,比如 Python 的
python-magic、Node.js 的file-type - 设置服务器级上传上限:
Nginx配client_max_body_size,Flask配MAX_CONTENT_LENGTH - 清理文件名:去掉路径(如
../../etc/passwd)、过滤特殊字符
最容易被忽略的是:表单本身若没配对 enctype="multipart/form-data" 和 method="post",文件根本传不到后端——哪怕 JS 校验再严,数据也卡在浏览器里发不出去。



















