问题背景:
一般正常来说,文件的上传就普通的调用接口,拿到返回值就行, 但是这次的需求可能是要上传的文件比较大(视频文件最大可上传2个g)。好吧,先还是用普通的接口来进行调用,像这么大的文件上传起来先设置较长的超时时间。,说是可能一个小时都有可能。然后nginx那边也有代理,也需要去设置超时时间。好吧,以这种方式尝试着,大文件上传着上传着,莫名其妙会出现奇奇怪怪的各种问题,后端说是每次问题都不一样。好吧,那可能需要换一种上传方式来。要么换成websocket长连接,要么还是分片上传。当我还在看websocket的时候,后端又说分片上传已经写好了,很好,我的后端yyds! 每次都直接高效的作出最佳选择。那就是下面前端的上传方式了,也没什么好说的,直接看一下代码实现吧。
代码实现:
async function handleUpload(file: any, func) {
if (Typer.isNull(file)) {
return message.error('未获取到文件')
// return logger.error("未获取到文件");
}
// const fileList = e.target.files as FileList;
// const file: File = fileList[0];
// 文件属性大小判断处理-随便写的
if (file.size > 2 * 1024 * 1024 * 1024 ) { // 文件大小最大为2g
console.log("文件过大");
} else {
const chunkSize = 3 * 1024 * 1024; // 3m
const totalChunks = Math.ceil(file.size / chunkSize);
// debugger
let uploadId = "";
for (let i = 0; i < totalChunks; i++) {
// 计算当前切片开始位置
const start = i * chunkSize;
// 当前切片结束位置
const end = Math.min(start + chunkSize, file.size);
// 切割数据
const chunk = file.slice(start, end);
// 转换blob
const chunkFile = new File([chunk], `${file.name}`, {
type: file.type,
});
// 设置请求参数
const formData = new FormData();
formData.append("file", chunkFile);
formData.append("partNumber", String(i + 1));
formData.append("partCount", String(totalChunks));
formData.append("uploadId", uploadId);
try {
// 发起上传请求
const response = await uploadShardingFile(formData);
if (response.code === 200) {
// 第1次之后携带后端返回uploadId
uploadId = response.data.uploadId;
if (response.data.ossUrl) {
func(file, response.data.ossUrl)
}
}
} catch {
message.error('上传失败')
console.log("上传失败=====>>>>>");
}
}
}
}
这样子,确实高效很多,视频也可以正常上传。下面大体讲述一下实现思路吧。
实现思路:
首先将文件进行切片处理,这里我们约定的是3M。 然后 按照切片后的大小,依次切片,进行传参。然后下一次的上传参数需要有上次接口返回的
uploadId。当拿到具体的视频路径后,跳出循环,说明上传完成。