大文件上传vue

之前做项目的时候遇到一个文件上传的问题,当时用没有考虑文件较大时,后端响应过长导致链接断开的问题。这个需求后来取消了,不过问题一直在,最近研究了下怎么解决这个问题。代码见

https://github.com/Mng12345/big-file-upload

,核心原理是前端使用Blob.slice方法对文件进行分块,下面是分块代码:

makeChunks(file: File): FileChunks {
    const fileChunks: FileChunks = {
      file,
      chunks: [],
    };
    if (file.size < this.chunkSize) {
      fileChunks.chunks.push({ start: 0, end: file.size });
      return fileChunks;
    }
    let chunksLength;
    if (file.size % this.chunkSize === 0) {
      chunksLength = Math.round(Math.floor(file.size / this.chunkSize));
    } else {
      chunksLength = Math.round(Math.floor(file.size / this.chunkSize)) + 1;
    }
    let leftSize = file.size;
    while (leftSize > 0) {
      const start = fileChunks.chunks.length * this.chunkSize;
      const end =
        start + this.chunkSize >= file.size
          ? file.size
          : start + this.chunkSize;
      leftSize -= end - start;
      fileChunks.chunks.push({ start, end });
    }
    return fileChunks;
  }

对每个chunk在上传时,共用一个随机生成的id用于后端合并子文件块

// 生成uid,传递给后端,后端根据uid对子文件块进行合并
    const fileUid = randomId();
    fileChunks.chunks.forEach(
      (chunk: { start: number; end: number }, index: number) => {
        const formData = new FormData();
        formData.append("index", index + "");
        formData.append("chunk", fileChunks.file.slice(chunk.start, chunk.end));
        formData.append("name", fileChunks.file.name);
        formData.append("chunksLength", fileChunks.chunks.length + "");
        formData.append("uid", fileUid);
        Axios.post<ChunkUploadResult>("/api/fileupload", formData)
          .catch((reason) => console.error(`error: ${JSON.stringify(reason)}`))
          .then((res) => {
            if (typeof res === "object") {
              const data = res.data;
              if (isChunkUploadResult(data)) {
                if (data.status) {
                  allChunksUploadStatus[index] = true;
                  // 更新上传百分比
                  this.uploadProcess = calUploadProcess();
                  // 更新上传状态
                  if (this.uploadProcess === 100) this.allChunksUploaded = true;
                }
              }
            }
          });
      }
    );

效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值