直接结论:用size控制大小(单位kb),用accept+exts+acceptmime三层组合限制格式,缺一不可;size限单文件体积,accept管系统选择框可见类型,exts校验文件名后缀,acceptmime精确控制mime过滤,四者协同方保安全。
直接结论:用 size 控制大小(单位 kb),用 accept + exts + acceptmime 三层组合限制格式,缺一不可。
size 设置文件大小限制,但注意单位是 KB 不是 MB
layui 的 size 参数单位固定为 KB,写成 size: 2048 表示 2MB,size: 5120 才是 5MB。如果误写 size: 5,实际只允许 5KB 文件(一张小图标都可能超)。
- 超过限制时,
before钩子不会触发,choose回调里也拿不到超限文件 —— layui 在底层就过滤掉了 - 错误提示靠
text["limit-size"]自定义,不设的话默认弹 “文件大小不能超过 XX KB” - 服务端仍需校验,因为前端限制可被绕过;
size只是用户体验层的第一道筛子
accept、exts、acceptMime 各司其职,单独用容易失效
accept 决定系统文件选择框初始筛选范围(如 images 会让 Windows/macOS 只显示图片类文件),但它只是“提示性分类”,不强制;exts 是上传前对文件名后缀的字符串匹配(如 "jpg|png|gif"),纯前端校验;acceptMime 才真正影响原生 <input type="file"> 的 accept 属性,控制操作系统级可见文件类型。
- 只设
accept: "file"→ 所有文件都可见,毫无限制 - 只设
exts: "zip|rar"→ 用户仍能选中 .exe 文件,直到before或choose里手动拦截 - 只设
acceptMime: "application/zip"→ 必须用标准 MIME(file/zip无效),且部分旧版 Safari 对 MIME 支持弱 - 推荐组合:
accept: "file"+exts: "zip|rar|7z"+acceptMime: "application/zip,application/x-rar-compressed,application/x-7z-compressed"
多文件上传时,size 和 exts 依然生效,但逻辑稍不同
开启 multiple: true 后,size 限制的是单个文件大小,不是总和;exts 会对每个文件单独校验后缀。用户一次选 10 个文件,只要其中任意一个超限或后缀不符,整个批次都会被拦在 choose 阶段外 —— 你甚至收不到 obj.getChooseFiles() 的完整列表。
- 想限制总大小?layui 原生不支持,得在
choose回调里遍历this.files手动累加.size -
exts匹配不区分大小写,但建议统一小写书写,避免"JPG|png"这类混写引发维护困惑 - 拖拽上传场景下,
acceptMime无效(浏览器不支持拖拽时的 MIME 过滤),此时完全依赖exts和before校验
before 钩子里做自定义校验,是最灵活也最容易漏掉的环节
很多开发者以为设了 size 和 exts 就万事大吉,结果发现 .zip 文件还是能传 .exe —— 因为后缀可以伪造。真正的防线在 before 函数里,它在文件发出前执行,且能拿到原始 File 对象。
- 校验文件头(magic number)需要读取
File.slice(0, 4)并转 ArrayBuffer,比后缀可靠得多,但会增加首帧延迟 - 检查
file.type字符串(如"application/zip")比exts多一层依据,但该字段由浏览器根据扩展名或 MIME 推断,不一定可信 - 务必
return false阻断上传,否则即使 console 报错,文件照样发出去 - 异步校验(如查用户权限)要用
return new Promise,否则 layui 会当作同步通过
真正难的不是配置哪几个字段,而是理解它们生效的时机和边界:系统级过滤(acceptMime)、命名层过滤(exts)、体积层拦截(size)、运行时深度校验(before)—— 四者不在同一层,漏掉任何一层,都可能让非法文件溜进后端。











