input type="file" 不支持 pattern 属性,需用 JavaScript 校验文件名后缀、MIME 类型及文件头,并兼顾移动端兼容性与空值处理。

pattern 属性对 file 类型完全无效
HTML 的 input type="file" 不支持 pattern 属性——浏览器会直接忽略它。这是最常踩的坑:写了 pattern=".*\.pdf$" 却发现提交时毫无反应。原因在于,file 输入框的 value 是伪路径(如 C:\fakepath\report.pdf),且原生校验逻辑只针对文本类输入(text、email、tel 等),不处理文件对象本身。
必须用 JavaScript 提取并校验文件名
真实可行的做法是监听 change 事件,从 files[0].name 中取原始文件名,再用正则判断后缀或整体格式:
- 用
file.name.split('.').pop().toLowerCase()安全提取扩展名(避免index.html.bak误判) - 匹配完整文件名时注意转义点号:
/^[a-z0-9_\-]+\.pdf$/i,不能写成.pdf(否则匹配任意字符) - 中文文件名需显式允许 Unicode:
/^[\u4e00-\u9fa5a-zA-Z0-9_\-]+\.(jpg|png|pdf)$/i - 校验失败后调用
input.setCustomValidity("不支持该格式"),否则checkValidity()仍返回true
别漏掉 MIME 类型的二次校验
仅靠文件名后缀不可靠,用户可手动改后缀绕过。必须同步检查 file.type 或读取文件头(如用 FileReader 读前 4 字节判断 PDF 是否真以 %PDF 开头):
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
-
file.type === "application/pdf"可作快速过滤,但可能为空(某些浏览器不提供) - 更稳妥的方式是结合后缀 + type:
ext === "pdf" && (file.type === "application/pdf" || file.type === "") - 服务端仍需重新校验,前端只是体验层防护
移动端和 Safari 的兼容细节
iOS Safari 对 input[type="file"] 的 files API 支持较弱,部分版本下 files.length 可能为 0 或 file.name 返回空字符串。建议:
立即学习“前端免费学习笔记(深入)”;
- 始终先判空:
if (!files || files.length === 0) return - 避免依赖
file.size做格式判断(有些系统不暴露) - 不要用
new RegExp(extPattern).test(file.name)在循环里反复创建正则对象,提前定义好实例


















