需求
项目需要大文件上传,大概3G左右的文件
思路
给大文件切片,1M为1片,每次控制并发100个请求,请求完后,再发100次请求,直至完成
实际
3G文件,5分钟左右,基本满足要求
代码
// 此处是上传文件核心代码
const uploadFile = async () => {
// 取出文件
const file = fileList.value[0];
console.log(file, "----file");
if (!file) {
// element的提示
ElMessage.error("未选择文件");
return;
}
if (!file.name.includes(".")) {
ElMessage.error("文件类型错误");
return;
}
if (file.name.length > 30) {
//判断文件大小
ElMessage.error("文件名大于30个字符");
return;
}
// 开始上传,设置标记位
fileButtonDisabled.value = true;
let chunkSize = 1024 * 1024 * 1; //分片大小1M
// 切片数量
let totalChunks = Math.ceil(file.size / chunkSize);
console.log("totalChunks------", totalChunks);
// 切片后,整个文件就靠这个编号识别了,就是文件的身份证
let identifier = Date.now().toString();
let ps = [];
for (let i = 0; i < totalChunks; i++) {
let start = i * chunkSize;
let end = Math.min(start + chunkSize, file.size);
let chunk = file.raw.slice(start, end);
let formData = new FormData();
formData.append("file", chunk);
formData.append("fileName", file.name);
formData.append("identifier", identifier);
formData.append("chunkIndex", i);
formData.append("totalChunks", totalChunks);
ps.push(formData);
}
let num = 0;
let limit = 100;
while (ps.length > 0) {
const listP = ps.splice(0, limit);
// 并发请求
await Promise.all(
listP.map(item => {
let f = api_upload_file(item);
f.then(() => {
sessionStorage.setItem("filePercentage", ++num);
// 此处可是获取到实际上传进度值
filePercentage.value = Math.floor(
(+sessionStorage["filePercentage"] / totalChunks) * 100
);
});
return f;
})
).catch(err => {
console.error(err);
ElMessage.error("文件分片上传失败");
});
}
// 请求后端合并
merge(identifier);
};
const merge = async identifier => {
let mergeFormData = new FormData();
mergeFormData.append("identifier", identifier);
// 请求完成之后,开始进行文件合并
await api_merge_file(mergeFormData)
.then(response => {
if (response.data.success == true) {
filePercentage.value = 100;
ElMessage.success("文件上传成功");
// 最终获取上传地址
dialogForm.dataFilePath = response.data.data.url;
dialogForm.dataFileName = response.data.data.name;
} else {
ElMessage.error(response.data.message);
}
})
.catch(err => {
ElMessage.error("文件上传失败");
console.error(err);
});
};