layui的exts参数默认大小写敏感,必须在choose或before回调中手动将文件后缀转小写后比对;accept和acceptMime不参与后缀校验,无法解决大小写问题。
exts 默认大小写敏感,必须手动转小写比对
layui 的 exts 参数本身不支持忽略大小写,它用 file.name.split('.').pop() 提取后缀后直接字符串匹配,所以 exts: "pdf" 会放过 report.pdf,但拦不住 readme.pdf。这不是 bug,是设计如此——它只做简单后缀截取和精确比对。
- 必须在
choose或before回调里手动处理:取file.name,用.toLowerCase()转小写,再用.split('.').pop()获取后缀 - 推荐统一用小写定义白名单,比如
const allowExts = ['pdf', 'docx', 'xlsx'] - 匹配时用
allowExts.includes(ext),别用indexOf或正则,避免误判.tar.gz这类双点名
为什么不能只靠 acceptMime 或 accept 解决大小写问题
accept 是浏览器弹窗的大类开关(如 images),acceptMime 控制 MIME 类型过滤(如 application/pdf),二者都不看文件名后缀,更不管大小写。用户把 hack.EXE 改成 invoice.PDF,acceptMime: "application/pdf" 会放行,exts: "pdf" 也会放行——因为后缀字符串确实是 PDF,只是没转小写。
-
acceptMime只影响系统选择框显示,不参与后缀校验 -
exts是纯字符串比对,不解析 MIME,也不读文件头 - 真正能统一大小写的唯一位置是 JS 回调里对
file.name的预处理
在 choose 回调中实现大小写无关的后缀检查
这是最常用也最可控的位置:用户选完文件、点击“打开”后立即拦截,还没触发读取或上传。关键是在 obj.files 上遍历,对每个文件做后缀标准化。
- 用
Array.from(obj.files)确保兼容性(IE11 下FileList不是真数组) - 提取后缀:
const ext = file.name.split('.').pop().toLowerCase() - 白名单校验:
if (!['jpg', 'jpeg', 'png'].includes(ext)) { layer.msg('仅支持 JPG/PNG 格式'); obj.reset(); return; } - 注意
obj.reset()必须在 return 前调用,否则下次选择仍残留非法文件
before 回调里做同样处理,但时机更晚
before 在文件读取开始后、上传发起前触发,此时 obj.getChooseFiles() 返回的是已通过 layui 内部 exts 初筛的文件列表。如果 exts 设了 "pdf",那 report.PDF 就不会进 before——它被 exts 拦在了外面,根本不会触发该回调。
- 想确保所有文件都走一遍大小写检查,必须关掉
exts(设为空字符串或删掉),全交给choose或before处理 -
before更适合需要读取文件内容(如 magic number)的场景,单纯后缀检查用choose更轻量、更早拦截 - 若同时用
exts和choose,exts会先筛一轮,可能漏掉大写后缀——这正是问题根源
exts 很少单独用;真正可靠的后缀控制,永远落在 choose 回调的手动比对上。别指望配置项自动帮你忽略大小写——那是你自己的事。











