松鼠的博客

导航

大文件、视频分片上传,断点续传

需求背景
再简单的需求,遇到巨大的任务量,也会变得很棘手
在项目中,难免会需要一些大的文件、视频上传,通常都会耗费很长的时间上传到服务器
然鹅,这其中不能出现任何的差错(网页刷新,关机、断网)之类的故障,一旦发生了,之前的努力都会付之东流,重新开始上传之路,这时候就体现出分片上传、断点续传的重要性了


1、分片上传
分片上传,就是将一个大的文件拆分成若干个小的文件,然后逐一进行上传,以缓解服务器的压力,
再通俗一点就是,把一张纸,撕成若干个小纸条,然后交给后端,后端再用胶水粘成一个完整的

将文件进行切割
async uploadFile (file) {
// file 获取当前上传的视频文件
let that = this
const CHUNK_SIZE = 1024 * 1024 * 20 // 每个块的大小为20MB
const chunks = Math.ceil(file.size / CHUNK_SIZE) // 计算文件分成多少块 总块数
let uploadedChunks = 0 // 已上传的块数
let uploadedBytes = 0 // 已上传的字节数
let progress = 0 // 上传进度

for (let i = 0; i < chunks; i++) {
const start = i * CHUNK_SIZE // 每块的起始位置
const end = Math.min(start + CHUNK_SIZE, file.size) // // 每块的末尾
const chunk = file.slice(start, end) // 将文件在指定的位置进行切割
const res = await that.uploadChunk(chunk, i, chunks, file.name) // 将每个模块执行上传方法
uploadedChunks++
uploadedBytes += end - start
progress = Math.floor(uploadedBytes / file.size * 20)
}

// 上传完成后的处理逻辑
console.log('上传完成')
},


上传单个模块
uploadChunk (chunk, index, totalChunks, fileName) {
let that = this
// 将chunk片段转换为File文件格式
let newChunk = new File([chunk], "分片文件", { type: "*", lastModified: Date.now() })
const formData = new FormData()
// 根据后端的需要,传参,文件上传传参:formData
formData.append('dir', 'cs')
formData.append('file', newChunk)
formData.append('blob_num', index)
formData.append('total_blob_num', totalChunks)
formData.append('blob_file_name', fileName)

return axios.post(baseURL, formData, {
headers: {
'Content-Type': 'multipart/form-data' // 文件上传格式
}
}).then(res => {
// 上传成功的处理
}).catch(err => {
console.log(err)
})
}


2、断点续传
只要弄明白了,分片上传,那断点续传就简单多了,还是前面的把文件分片

let uploadedChunks = 0 // 已上传的块数
1
每次上传的时候,给后端传一个状态(当前第几片),然后触发上传之前请求一次后端接口,看上一次给后端传了几个片段,将状态后面的片段上传给后端
这个就可以做上传的暂停,开始操作

参考文章:http://blog.ncmem.com/wordpress/2023/12/22/%e5%a4%a7%e6%96%87%e4%bb%b6%e3%80%81%e8%a7%86%e9%a2%91%e5%88%86%e7%89%87%e4%b8%8a%e4%bc%a0%ef%bc%8c%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0/

欢迎入群一起讨论

 

 

posted on 2023-12-22 16:18  Xproer-松鼠  阅读(50)  评论(0编辑  收藏  举报