分片并发上传实现

先上流程图

文件上传步骤

1.文件分片处理:将文件按 5MB 大小切分为多个 Blob 分片,并发送文件信息至后端。

2.获取预签名 URL:后端为每个分片生成预签名上传 URL,并返回给前端,用于前端上传。

3.并发上传分片:前端控制最多同时 3 个上传任务,逐个发起 PUT 请求上传分片。上传成功则继续下一个分片,上传失败则自动重试,自动重试最多 3 次。

4.所有分片上传成功后,调用后端合并接口,完成文件上传。

一、文件切片处理

   使用 File.slice() 将文件切分为多个 Blob

文件切片好处

1. 拆分为小片,避免因网络波动导致整体上传的失败,支持断点续传。

2. 并发上传多个分片,可以缩短整体上传时间。

3. 若上传失败仅需重传失败的分片,无需重复上传整个文件。

4. 可控制单次请求大小,避免超时或内存溢出。  

为什么使用 Blob 而非 FileBuffer

        用 Blob 可以有效降低内存占用

Blob 是惰性加载的

   Blob 对象本身并不立即将文件内容加载到内存中。它更像是一个指向文件某部分的“引用”。只有当真正读取 Blob 内容时(例如通过 FileReaderResponse API),数据才会被加载。

ArrayBuffer/Buffer 是内存驻留的

         创建 ArrayBuffer 意味着立即将切片的数据复制到内存中,占用实际的内存空间。对于大文件,这会导致内存占用急剧上升,可能引发性能问题或内存溢出。

具体代码:

export const getFileChunk = async (file, chunkSize = 8 * 1024 * 1024) => {
  const chunks = await getFileChunkAsBlob(file, chunkSize)
  return chunks
}

// 只分片不读取数据,返回 Blob
const getFileChunkAsBlob = (file, chunkSize) => {
  return new Promise(resolve => {
    const blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
    const chunks = Math.ceil(file.size / chunkSize)
    const chunksMap = {}

    // 循环生成 Blob 分片
    for (let i = 0; i < chunks; i++) {
      const start = i * chunkSize
      const end = Math.min(start + chunkSize, file.size)
      chunksMap[i + 1] = blobSlice.call(file, start, end) // 返回 Blob
    }

    resolve(chunksMap)
  })
}

二、获取分片上传 URL(URL 经过预签名)

        预签名 URL 是一个带有临时授权信息(如签名、过期时间、权限范围)的 URL,由后端使用云存储的访问密钥(Access Key / Secret Key)生成,允许前端通过该 URL 直接上传或下载。

核心目的避免暴露长期密钥,安全地授权第三方临时访问受保护的资源。

预签名 URL好处

        1. 精确控制操作类型(如只能上传或下载)

        2. 控制URL过期时间

        3. 控制只能访问某个特定文件

具体:调用后端接口,获取每个分片的上传地址和 uploadId。

【代码略,涉及业务逻辑,后期更新】

三、并发上传分片(带重试)

        前端启动上传时,使用一个并发控制队列,控制最多同时发起 3 个分片上传请求。维护一个待上传任务列表,每次从队列中取出一个分片,通过预签名 URL 发起 PUT 请求上传。

上传成功

        后端返回 200 ,并携带 ETag 头。前端记录该分片的 partNumberETag,更新上传进度,并继续发起下一个分片的上传。

上传失败

        若请求因网络问题、超时等失败,则将该分片标记为“待重试”,并将其加入重试队列。

        1. 每个分片最多重试 3 次

        2. 重试采用指数退避策略:第一次失败后等待 1 秒,第二次等待 2 秒,第三次等待 4 秒再发起。

        3. 若 3 次重试均失败,则整个上传任务中断,提示用户“上传失败,请检查网络后重试”。

指数退避策略

        在网络抖动服务器短暂过载时,密集重试会加剧问题,甚至导致服务崩溃,指数退避让每次重试的等待时间成倍增长,不会在同一时间重试,分散请求压力。

具体:使用 并发控制 + 重试机制 上传分片:

【代码略,涉及业务逻辑,后期更新】

四、合并分片(Merge)

        所有分片上传成功后,通知服务器合并

【代码略,涉及业务逻辑,后期更新】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值