原理
关于断点续传,相比大家都应该接触过,比如下载暂停,下一次点击开始可以继续下载,如果没有断点续传,那么只要停一下,那么就全听了,下一次开始会重新下载。
原理的话(拿上传为例),就是将一个文件分成多份(切片)上传,然后记录上传到哪一个切片,下一次就继续上传上次暂停的切片继续上传,等所有切片都上传完成,就合并所有文件。
前端切片代码
可以将文件按大小或按份数进行切片,下面代码是按大小切片的
md5值是文件的唯一标识,也可以根据文件的md5值进行秒传(每次上传,校验md5值,若数据库中有该值,则为同一个文件,仅仅复制数据库文件地址即可,不用重复上传)
import axios from "axios";
import SparkMD5 from 'spark-md5'
const upload = {
uploadFile(file, chunkSize, url) {
const fileReader = new FileReader();
const spark = new SparkMD5.ArrayBuffer()
fileReader.readAsArrayBuffer(file)
fileReader.onload = async function (e) {
spark.append(e.target.result)
const md5 = spark.end();
let uploadedSize = 0;
const fileSize = file.size;
// 向上取整
const totalChunks = Math.ceil(fileSize / chunkSize);
while (uploadedSize < fileSize) {
// 因为最后一次可能会超出文件总大小,所以取文件总大小
const endSlice = Math.min(uploadedSize + chunkSize, fileSize);
const blob = file.slice(uploadedSize, endSlice);
const formData = new FormData();
formData.append('file', blob);
formData.append('start', uploadedSize);
formData.append('end', endSlice);
formData.append('totalChunks', totalChunks);
formData.append('md5', md5);
const data = {
};
formData.forEach((value, key) => data[key] = value);
console.log(data)
const response = await axios.post(url, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
});
if (response.data.code === 200) {
} else {
throw new Error("");
}
}
}
}
}
export default upload;
后端接收代码
。。。后秒再补