项目背景:vue2.7+elementui。
最近在做一个上传功能时,测试提出了一个故障,故障内容:上传选择文件之后,本地文件移动了,或者删除了,这个时候点击上传会报错,但是这个错误是浏览器抛出的,测试希望得到的提示是“以下文件读取失败:{fileName},请确认本地文件是否被删除或移动”,接到这个故障时脑海中立马出现了两种方案,方案一是使用window.addEventListener("error")来做异常拦截,方案二读取本地文件的一个片段,读到了就说明文件无恙,读不到排除异常提示。最终在以不够装逼排除了方案一,选择了方案二。具体实现如下:
首先创建一个方法读取文件片段
function readFileChunk (file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(true);
reader.onerror = () => reject(false);
reader.readAsArrayBuffer(file.slice(0, 1)); // 尝试读取文件的前一个字节
});
}
其次创建一个方法批量校验文件,并返回校验结果
function validateFiles (files) {
const promises = files.map(file => {
return readFileChunk(file.raw).then(
() => ({ file, result: true }), // 文件可访问
() => ({ file, result: false }) // 文件读取失败
);
});
// 使用 Promise.all 来等待所有文件的验证结果
return Promise.all(promises).then(results => {
// 筛选出所有验证失败的结果
const failedResults = results.filter(result => !result.result);
if (failedResults.length > 0) {
// 如果有文件验证失败,抛出错误信息
const fileName = failedResults.map(fr => fr.file.name).join(',');
const errorMessage = `以下文件读取失败:{fileName},请确认本地文件是否被删除或移动`;
throw new Error(errorMessage);
}
// 所有文件验证通过
return true;
});
}
最后使用:
function upload () {
const files = files.value;// 文件列表
validateFiles(files).then(() => {
调用上传接口
})
.catch(error => {
// 处理文件验证失败的情况
if (error.message) {
proxy.$message.error(error.message);
};
});
}
提示效果如下
Time!