唯一可靠判断空文件的依据是 obj.files[i].size === 0,因其不依赖读取内容、无io开销且浏览器选择瞬间即提供;不可用 obj.preview() 或 filereader,因会冗余异步、兼容风险高且无法中断;校验须在 choose 回调内进行,配合 obj.reset() 清空并提示,同时防御性检查 f.size == null || f.size === 0。
文件内容为空,本质是文件体积为 0 字节,obj.files[i].size === 0 就是唯一可靠判断依据——它不依赖读取文件内容,也不触发任何 io,浏览器在选择瞬间就已提供该值。
为什么不能用 obj.preview() 或 FileReader 判断空文件
很多人误以为要“读一下内容”才能知道是否为空,于是用 obj.preview() 或手动 new FileReader() 去读取。这是高风险操作:
-
obj.preview()在文件 size 为 0 时仍会执行 FileReader 流程,但某些旧版 Layui(如 2.8.x)对空文件 fallback 不完整,回调里的file可能丢失name或size属性 - 即使成功读取,
FileReader.result对空文件返回空字符串或 ArrayBuffer 长度为 0,但你已经多走了一趟异步流程,纯属冗余 - 空文件本身极少,但若批量上传中混入空文件,用 preview 逐个读取会拖慢整个队列,且无法中断
choose 回调里直接读 size 是最简方案
所有校验必须放在 choose 回调内,此时 obj.files 是原生 FileList,每个 File 实例都带 size 属性:
- 单文件:检查
obj.files[0].size === 0 - 多文件:遍历
Array.from(obj.files),对每个f.size === 0做过滤或提示 - 注意:IE10+ 支持,IE9 及以下无
FileList,需降级(如禁用上传按钮并提示“浏览器版本过低”) - 别在
before里判断——此时文件流已发出,后端可能已开始接收,前端再拦已晚
校验逻辑要配合 obj.reset() 和用户反馈
发现空文件后,不能只提示,必须主动清空选择,否则用户重复点击上传按钮会再次触发:
- 用
layer.msg('文件内容为空,请重新选择')提示,避免alert阻塞 UI - 立即调用
obj.reset(),清空当前选中的空文件(Layui 2.9+ 已修复 reset 后 input value 清零问题) - 如果允许多选且仅部分为空,不要
reset()全部,而是过滤出非空文件,再对每个合规文件调用obj.upload({data: {filename: f.name}}) - 别试图修改
obj.files——它是只读的,赋值无效
真正容易被忽略的是:空文件的 size 一定是 0,但某些异常情况(如浏览器 Bug、挂载磁盘故障)可能导致 size 返回 null 或 undefined;稳妥做法是加一层防御:if (f.size == null || f.size === 0)。这不是理论风险,2026 年 5 月 Safari 17.5 在某类 NAS 挂载路径下就出现过 size 为 undefined 的案例。











