Layui upload的done回调不判断失败,失败由error回调处理,其第三个参数index标识出错文件在choose时的原始顺序;需在choose中缓存文件信息,并在error中通过data-index匹配预览DOM进行高亮标记。
done 回调里怎么判断哪个文件上传失败
layui upload 的 done 回调本身不区分成功/失败——它只在「服务端返回标准 json 且 code === 0」时触发。真正标记失败,得靠 error 回调 + 文件索引对齐。
关键点:多文件上传时,error 回调的第 3 个参数 index 就是当前出错文件在原始队列中的位置(从 0 开始),和 choose 时拿到的顺序一致。
-
error触发时,index可靠;但done不会为失败文件调用 - 必须在
choose阶段就缓存所有文件元信息(如name、size),否则error里拿不到文件名 - 不要依赖
obj.files在error中还存在——它可能已被清空或失效
如何把失败文件高亮显示在预览区
预览区通常是手动用 FileReader 插入的 <img> 或占位容器。标记失败,就是在对应 DOM 节点上加样式或提示文案。
示例逻辑(放在 error 回调内):
error: function (index, upload) {
const previewItem = document.querySelector(`#preview-box [data-index="${index}"]`);
if (previewItem) {
previewItem.style.border = '2px solid #ff5722';
previewItem.title = '上传失败,请重试';
}
}
- 确保每个预览节点有唯一
data-index属性,值与choose时遍历的i一致 - 避免用 class 名做索引(比如
.file-1),DOM 操作易受干扰;data-属性更稳定 - 如果预览区用了
layui-carousel或其他组件包裹,需确认其内部结构是否屏蔽了自定义属性访问
后端返回非 0 code 时,前端怎么统一收集错误文件
有些后端接口对多文件采用「单次请求、批量响应」模式(即 unified: true),此时所有文件结果都在一个 JSON 里返回,done 仍会触发,但需手动解析哪些失败。
这时不能依赖 index 参数,而要解析服务端返回的数组字段(如 res.data.results):
done: function (res) {
if (Array.isArray(res.data?.results)) {
res.data.results.forEach((item, i) => {
if (item.code !== 0) {
markFileAsFailed(i, item.msg);
}
});
}
}
-
unified: true下index参数无意义,它始终是0 - 务必校验
res.data.results是否存在且为数组,防止 JS 报错中断流程 - 后端字段命名不统一很常见(比如叫
list、files、items),需按实际接口约定调整
容易被忽略的边界情况
标记失败不只是加红框,还要考虑用户后续操作是否连贯。这些点一旦漏掉,UI 就会“假死”或误导用户。
- 已标记失败的文件,再次点击上传按钮时,
choose回调不会自动重新触发——得清空input[type="file"]的value或用obj.upload()显式重传 - 如果用了
before构造FormData,失败后重传需确保FormData里附带的额外参数(如category)仍是最新值 - IE10/11 下
error回调可能不触发(尤其跨域场景),需 fallback 到xhr.status !== 200判断











