我们在进行大文件上传时,如果遇到网络或者其他问题,中途中断了上传,用户体验会非常差,这时候我们就应该使用分片上传
前端实现原理及重点代码如下,直接看代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- spark-md5在工程化项目中也可通过npm安装 -->
<script src="./spark-md5.js"></script>
</head>
<body>
<input type="file" />
<script>
const inp = document.querySelector('input');
// 监听上传事件
inp.onchange = async (e) => {
const file = e.target.files[0];
if (!file) {
return;
}
// 将文件以10M一个分片,得到一个都是blob对象的数组
const chunks = createChunks(file, 10 * 1024 * 1024);
// 获取一个文件hash,相当于这个文件的身份证号码
const result = await hash(chunks);
console.log(result)
console.log(chunks)
// 得到文件hash和分片数组后自行上传到后端...
}
// 根据分片计算文件hash
function hash(chunks) {
return new Promise((resolve) => {
const spark = new SparkMD5();// 使用SparkMD5得到一个16位的hash值
function _read(i) {
if (i >= chunks.length) {// 递归结束条件
resolve(spark.end());// spark.end()结束增量运算,返回一个结果
return;// 读取完成
}
const blob = chunks[i];
const reader = new FileReader();// 创建文件读取器
reader.onload = (e) => {
const bytes = e.target.result;// 读取到的字节数组
spark.append(bytes);// 增量运算
_read(i + 1);// 递归调用
}
reader.readAsArrayBuffer(blob);// 将blob类型读取为字节
}
_read(0);
});
}
// 分片
function createChunks(file, chunkSize) {
const result = [];
for (let i = 0; i < file.size; i += chunkSize) {
result.push(file.slice(i, i + chunkSize));
}
return result;
}
</script>
</body>
</html>