ToB企服应用市场:ToB评测及商务社交产业平台

标题: 前端大文件分片上传 [打印本页]

作者: 火影    时间: 2024-6-11 11:04
标题: 前端大文件分片上传
1.分片上传整体流程



2.前端具体流程


3.部分代码

  1. //文件切片,utils
  2. import SparkMD5 from 'spark-md5'
  3. export async function getChunkList (files) {
  4.         const file = files
  5.         console.log(file);
  6.         const fileSize = file.size // 文件大小
  7.         const fileName = file.name
  8.         let chunkSize = 0;
  9.         if (fileSize <= 5 * 1024 * 1024) { // 0-5M,不分片
  10.                 chunkSize = fileSize;
  11.         } else if (fileSize <= 20 * 1024 * 1024) { // 5-20M,每个分片大小1M
  12.                 chunkSize = 1024 * 1024;
  13.         } else if (fileSize <= 50 * 1024 * 1024) { // 20-50M,每个分片大小2M
  14.                 chunkSize = 2 * 1024 * 1024;
  15.         } else if (fileSize <= 100 * 1024 * 1024) { // 50-100M,每个分片大小4M
  16.                 chunkSize = 4 * 1024 * 1024;
  17.         } else if (fileSize <= 200 * 1024 * 1024) { // 100-200M,每个分片大小6M
  18.                 chunkSize = 6 * 1024 * 1024;
  19.         } else if (fileSize <= 500 * 1024 * 1024) { // 200-500M,每个分片大小10M
  20.                 chunkSize = 10 * 1024 * 1024;
  21.         } else if (fileSize <= 1024 * 1024 * 1024) { // 500M-1G,每个分片大小20M
  22.                 chunkSize = 20 * 1024 * 1024;
  23.         } else { // 1G以上,每个分片大小20M
  24.                 chunkSize = 20 * 1024 * 1024;
  25.         }
  26.         const totalChunks = Math.ceil(fileSize / chunkSize)
  27.         let start = 0
  28.         let end = Math.min(chunkSize, fileSize)
  29.         let index = 0 // 分片索引,从0开始
  30.         const chunks = [] // 存储当前文件的分片信息的数组
  31.         while (start < fileSize) {
  32.                 const chunk = file.slice(start, end)
  33.                 const reader = new FileReader()
  34.                 const promise = new Promise((resolve, reject) => {
  35.                         reader.onload = (e) => { //读取文件分片信息,使用SparkMD5库计算分片的MD5值
  36.                                 const spark = new SparkMD5.ArrayBuffer()
  37.                                 spark.append(e.target.result)
  38.                                 resolve(spark.end())
  39.                         }
  40.                         reader.onerror = (err) => {
  41.                                 reject(err)
  42.                         }
  43.                 })
  44.                 reader.readAsArrayBuffer(chunk)
  45.                 try {
  46.                         const md5 = await promise
  47.                         const chunkInfo = { chunk, md5, index }
  48.                         chunks.push(chunkInfo)
  49.                 } catch (err) {
  50.                         reject(err)
  51.                 }
  52.                 //更新循环起止位置
  53.                 start = end
  54.                 end = Math.min(start + chunkSize, fileSize)
  55.                 index++
  56.         }
  57.         // 将当前文件的分片信息数组存入总的数组中
  58.         return [chunks, totalChunks, fileSize, fileName, chunkSize] // 返回存储所有文件的分片信息的数组
  59. }        
复制代码
  1. async handleUpload () {
  2.                         this.progressState = 'upload'
  3.                         this.wrongNum = 0
  4.                         if (this.fileList.length == 0) { //判断是否添加文件
  5.                                 this.$notify.warning({
  6.                                         title: this.$global.warningMessage.title,
  7.                                         message: this.$global.warningMessage.fileMessage,
  8.                                 });
  9.                                 return
  10.                         }
  11.                         if (this.file.name.length > 256) {
  12.                                 this.$notify.warning({
  13.                                         title: this.$global.warningMessage.title,
  14.                                         message: this.$global.warningMessage.fileNameMessage,
  15.                                 });
  16.                                 return
  17.                         }
  18.                         this.totalSize = this.file.size
  19.                         // 调用getChunkList方法获取分片及相关信息
  20.                         const [chunks, totalChunks, fileSize, fileName, chunkSize] = await getChunkList(this.file.raw)
  21.                         this.totalChunks = totalChunks
  22.                         this.fileSize = fileSize
  23.                         this.fileName = fileName
  24.                         this.chunkList = chunks
  25.                         this.chunkSize = chunkSize
  26.                         console.log(this.chunkList);
  27.                         // 开始上传请求
  28.                         await this.startUpload()
  29.                         // 遍历分片信息数组,取出除文件分片外的其他信息
  30.                         const sessionChunkList = this.chunkList.map(({ chunk, ...rest }) => rest);
  31.                         // 将分片其他信息存入sessionStorage中
  32.                         sessionStorage.setItem("chunkData", JSON.stringify(sessionChunkList));
  33.                         let i = 0;
  34.                         while (i < this.chunkList.length && this.wrongNum < 1) { //对分片数组进行遍历
  35.                                 const chunkInfo = this.chunkList[i];
  36.                                 const res = await this.uploadChunk(chunkInfo); //调用上传分片方法
  37.                                 if (res.data.state == 200) {
  38.                                         const removeInfo = {
  39.                                                 md5: chunkInfo.md5,
  40.                                                 index: chunkInfo.index
  41.                                         }
  42.                                         await this.handleSuccess(removeInfo, chunkInfo) //调用当前分片上传成功处理函数
  43.                                         i++;
  44.                                 } else {   //上传未成功,重新上传一次
  45.                                         const res = await this.uploadChunk(chunkInfo);
  46.                                         this.wrongNum += 1
  47.                                         if (res.data.state == 200) {
  48.                                                 this.wrongNum = 0
  49.                                                 await this.handleSuccess(removeInfo, chunkInfo)
  50.                                                 i++;
  51.                                         } else {  // 重新上传一次后仍未成功
  52.                                                 const state = this.$global.completeUploadState.cancelUpload
  53.                                                 await this.completeUpload(state)
  54.                                                 this.$notify.error({
  55.                                                         title: this.$global.failedMessage.title,
  56.                                                         message: res.data.message
  57.                                                 });
  58.                                                 this.handleClear()
  59.                                                 return
  60.                                         }
  61.                                 }
  62.                         }
  63.                 }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4