accept属性仅提示不强制,iOS Safari上基本失效;前端校验需依赖文件名扩展名和大小,后端必须用魔数校验文件头并清理文件名,form须设post、multipart/form-data及name属性。

accept 属性不能强制限制图片格式,它只影响文件选择器的初始过滤界面,用户点“所有文件”就能绕过。真正卡住格式的地方在服务端对字节流的解析,前端校验只是减少无效请求、加快反馈。
为什么 accept 在 iOS Safari 上基本失效
iOS Safari 对 accept 的实现非常宽松:accept="image/jpeg,image/png" 不会阻止用户选 HEIC、WebP 甚至 .txt;accept="image/*" 能唤起相册,但拍出来的图格式由设备决定(比如 iPhone 默认是 HEIC)。这不是 bug,是规范允许的行为——accept 本意就是提示,不是守门员。
input[type="file"] 前端校验必须靠 file.name 和 file.size
file.type 字段在 Windows 下双击选文件时经常为空,不能依赖。可靠做法是:
- 用
file.name.toLowerCase().endsWith('.jpg')或正则/\.(jpe?g|png|gif|webp)$/i检查扩展名 - 同时校验大小:
file.size > 5 * 1024 * 1024就清空input.value并提示 - 如需更严,可读取前 4 字节做魔数判断(PNG 是
89 50 4E 47),但多数业务扩展名已够用
后端必须用文件头(magic bytes)而非扩展名或 Content-Type 校验
前端所有检查都可被禁用 JS、改后缀、抓包重发绕过。关键动作包括:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
立即学习“前端免费学习笔记(深入)”;
- 不信任
Content-Type请求头或文件扩展名,用库解析真实文件头(如 Python 的python-magic,Node.js 的file-type) - 拒绝
image/bmp、image/vnd.microsoft.icon等非预期但 MIME 匹配的类型 - 清理文件名:去掉路径(
../../)、特殊字符,重命名成随机字符串 + 安全后缀 - Nginx 或应用层设上传体大小上限(如
client_max_body_size 10M)
form 基础配置错,整个限制就归零
即使前后端都写了校验,如果表单结构不对,文件根本传不到后端:
-
method必须是post -
enctype必须设为multipart/form-data(缺了它,input[type="file"]字段在后端收不到) -
input[type="file"]必须有name属性,否则后端无法通过字段名提取文件
真正容易被忽略的是:移动端调用摄像头时加了 capture="environment",此时 accept 会被浏览器直接忽略,拍出格式完全由设备决定——你得在服务端兜底识别并拒绝非目标格式。


















