文件原始名称(含后缀)只能在choose回调中通过obj.files[0].name获取,且需用lastIndexOf安全截取后缀;before/done回调中obj.files已为空,IE9及以下不支持FileList,Safari对超大文件size可能为0。
choose回调里直接读obj.files[0].name是唯一可靠时机
文件原始名称(含后缀)只能在choose回调中通过obj.files获取,错过就没了。layui 2.9.x 后,before和done回调里的obj不再携带files属性,强行访问会报undefined或空数组。
常见错误包括:
- 在
before里写obj.files[0].name——此时obj.files已为空 - 误用
obj.pushFile()返回值当File对象——它只返回队列ID映射,不含name或size - 依赖
obj.preview()回调里的file.name——该file是预览副本,大文件下可能丢失属性
正确做法:在choose里立刻处理obj.files,它是标准原生FileList,每个元素都有name属性。
用String.prototype.lastIndexOf安全截取后缀名
obj.files[0].name返回的是完整原始文件名(如"report_v2.pdf"),后缀名需手动提取。不能硬切.pdf这种固定字符串,得按最后一个点号位置拆分。
推荐写法:
const fileName = obj.files[0].name;
const dotIndex = fileName.lastIndexOf('.');
const ext = dotIndex > 0 ? fileName.slice(dotIndex) : '';
注意点:
- 文件名可能无点号(如
"README"),lastIndexOf返回-1,直接slice(-1)会出错,必须加> 0判断 - 不要用
fileName.split('.').pop()——遇到"my.file.name.txt"会错取"txt"而非".txt" - 后缀名含点号(如
".jpg"),保留点更利于后续acceptMime匹配或后端校验
obj.files在IE10+可用,IE9及以下需降级处理
FileList是HTML5特性,IE9及更低版本不支持,obj.files会是undefined或空对象。此时无法可靠读取原始名,只能依赖input.value(但IE9下该值是假路径,如"C:\fakepath\abc.jpg")。
兼容建议:
- 检测
obj.files && obj.files.length,为false时走降级逻辑 - 降级方案:用
document.querySelector('input[type="file"]').value,再正则提取fakepath后的内容 - 更稳妥做法:直接提示“请使用 IE10+ 或 Chrome/Firefox 浏览器”并禁用多选功能
别试图用obj.preview()绕过——它在IE9根本不可用,且同样拿不到原始name。
大文件下name依然有效,但size在Safari可能为0
即使文件超2GB,obj.files[0].name和obj.files[0].size在Chrome/Firefox/Edge中仍能秒取。这是浏览器在选择瞬间就解析出的元信息,不触发文件读取。
但Safari有个已知限制:对超大文件(尤其>4GB),size返回0,而name始终可用。所以后缀提取逻辑不受影响,但校验大小时要加兜底:
const file = obj.files[0];
const name = file.name;
const size = file.size || 0; // Safari下size可能为0
if (size === 0) {
layer.msg('文件大小暂不可读,请确认浏览器版本');
}
真正容易被忽略的是:后缀名提取后,别忘了和服务端约定一致(比如是否强制小写、是否允许空后缀)。前端拿到".PDF",后端若只认".pdf",上传就会被拒。











