accept 属性应填写具体字体 MIME 类型与扩展名组合,如".woff,.woff2,.eot,.ttf,.otf,.ttc,application/font-woff,font/woff2,application/vnd.ms-fontobject,font/ttf,font/otf,font/collection",逗号分隔无空格。

accept 属性该填什么 MIME 类型或扩展名
字体文件没有单一通用 MIME 类型,不同格式需分别指定。直接写 accept="font/*" 无效,浏览器不识别。必须显式列出常见字体类型及其对应值:
-
application/font-woff(WOFF) -
font/woff2(WOFF2,现代推荐) -
application/vnd.ms-fontobject(EOT) -
font/ttf或application/x-font-ttf(TTF) -
font/otf或application/x-font-opentype(OTF) -
font/collection(TTC)
实际使用时建议组合写法,兼顾兼容性与移动端支持:accept=".woff,.woff2,.eot,.ttf,.otf,.ttc,application/font-woff,font/woff2,application/vnd.ms-fontobject,font/ttf,font/otf,font/collection"。注意:逗号分隔、无空格;.woff2 要放在 font/woff2 前面,因 Safari 对 MIME 支持弱,优先靠扩展名兜底。
为什么只靠 accept 无法真正限制字体上传
用户在文件选择对话框中点击“所有文件”就能绕过 accept 过滤,选中任意后缀的文件(比如把 malware.exe 改名为 safe.woff)。更麻烦的是:input.files[0].type 在多数浏览器里对字体文件返回空字符串或不可靠值(尤其拖拽上传时),不能用来判断真实类型。
前端唯一较可靠的检查方式是取扩展名:file.name.split('.').pop().toLowerCase(),再比对白名单数组 ['woff', 'woff2', 'eot', 'ttf', 'otf', 'ttc']。但这仍防不住改后缀攻击——它只是体验层提示,不是安全边界。
立即学习“前端免费学习笔记(深入)”;
后端必须校验字体文件头(Magic Bytes)
真正能确认一个文件是不是字体,只能靠读取文件前若干字节的魔数(magic bytes)。例如:
-
woff:开头 4 字节为77 4F 46 46(ASCII "WOFF") -
woff2:开头 4 字节为77 4F 46 32(ASCII "WOFF2") -
ttf/otf:前 4 字节通常为00 01 00 00、4F 54 54 4F("OTTO")、74 72 75 65("true")等
Node.js 可用 file-type 包(支持 WOFF/WOFF2/TTF/OTF):await fileType.fromBuffer(buffer);PHP 推荐 finfo_open(FILEINFO_RAW) 配合自定义规则;Python 用 python-magic 时需加载字体专用 magic 数据库。别信 $_FILES['font']['type'] 或 req.file.mimetype,它们全由客户端控制,形同虚设。
form enctype 和 name 不配对会导致后端收不到文件
哪怕 accept 写得再全,如果表单漏了关键属性,后端永远拿不到文件:
-
<form>必须带enctype="multipart/form-data",否则文件字段被忽略,req.files为空或根本不存在该 key -
<input type="file">必须有name属性(如name="fontFile"),后端靠它索引上传内容,没 name 就等于没传 - 若用
multiple允许多选,后端接收时要注意字段名是否带[](如name="fontFiles[]"),否则只取到第一个
常见错误现象:req.file is undefined(Express + multer)、$_FILES 为空数组(PHP),但控制台无报错——问题往往卡在 HTML 层,而非 JS 或后端逻辑。
字体文件类型判断的复杂点在于:同一格式在不同系统、不同浏览器上报的 type 差异极大,而魔数校验又必须读完整 header(至少前 12 字节),不能只看扩展名。最容易被忽略的是——连 enctype 这种基础配置,都常被当成“默认就有”而遗漏。



















