前端大文件断点续传和分片续传

有时候我们开发后台管理系统的时候,比如官网后台,需要上传很多宣传图片或者宣传视频什么的。 当视频或图片的比较大的时候,有可能经常会碰到页面卡着不动的情况,然后时间久了以后要不是报错,要不就是失败了,那么遇到这种情况该怎么办呢?
那就只能分片上传或者断点续传了,今天我们就分析分析这个方法。

一、 分片上传

分片上传的思路就是把某个整体进行拆解,然后逐个上传,等成功以后再进行拼接的一个过程

  1. 前端分片切割

    javascript 复制代码
    // 假设我们有一个来自 input[type=file] 的 File 对象
    const file = document.getElementById('fileInput').files[0];
    const chunkSize = 5 * 1024 * 1024; // 每片 5MB (可调整)
    let start = 0;
    let chunkIndex = 0;
    const chunks = [];
    
    while (start < file.size) {
      const end = Math.min(start + chunkSize, file.size);
      const chunk = file.slice(start, end); // 关键API:Blob.slice()
      chunks.push({
        index: chunkIndex,
        file: chunk,
        totalChunks: Math.ceil(file.size / chunkSize),
        fileName: file.name,
        fileSize: file.size,
        chunkSize: chunkSize,
        // 强烈建议添加唯一标识,用于后端重组和去重
        fileIdentifier: generateFileHash(file) // 如计算MD5/SHA(可异步)
      });
      start = end;
      chunkIndex++;
    }
  2. 分片上传 : 前端通过循环请求将每个 chunk 对象独立上传到服务器。每个请求只携带文件的一小部分。

  3. 后端接收与存储 : 后端接收到每个分片后,根据请求中的标识信息(如 fileIdentifier + chunkIndex)将其临时存储。分片通常先存磁盘或对象存储,而非直接入库。

二、 断点续传

段带你续传我们从字面意思理解就是:当正在上传过程中断了,等恢复正常以后继续从之前上传的地方开始,比如 网络闪断、用户误关页面、服务器重启... 上传中断是常态。

  1. 前端记录

    • 在上传每个分片前,将分片索引(chunkIndex)等信息持久化存储(localStorage, IndexedDB, 甚至服务器)。
    • 上传成功后,标记该分片完成。
    • 当需要恢复上传时,先读取存储的状态,找出哪些分片还没传,只上传这些缺失的分片。
  2. 服务端支持

    • 提供 /check-upload 接口:前端在开始上传(或恢复上传)前,携带 fileIdentifier 询问后端哪些分片已存在。
    • 后端根据 fileIdentifier 查找已存储的分片列表(如索引数组 [0, 1, 3, 4]),返回给前端。
    • 前端对比已有分片列表,只上传缺失的分片(如索引 2)。
  3. 最终合并

    • 前端在检测到所有分片上传完成后,发送一个 /merge 请求给后端。
    • 后端根据 fileIdentifier,找到所有属于该文件的分片,按索引顺序拼接(concat)成完整的原始文件。
    • 合并完成后,删除临时分片文件,将完整文件移动到永久存储位置,返回最终文件地址。

三、经验总结

  1. 分片的大小要合适

    • 当太小时:请求的数量太多了,这样的话建立的连接也多,到时候很有可能触发后端设置的频率限制。
    • 当太大时:失去分片意义,单个分片上传失败代价高。
    • 合适大小:1MB ~ 10MB 是常见范围。考虑实际网络环境和后端处理能力。
  2. 文件标识必须使用文件内容生成唯一标识(如 MD5, SHA-1, SHA-256),确保前后端生成逻辑一致。

  3. 服务端合并

    • 文件覆盖 :如果出现多个用户上传同名文件的话,fileIdentifier 不同,会导致文件冲突的,最终存储路径应包含 fileIdentifier 或唯一 ID,而非单纯依赖原始文件名。
相关推荐
huabuyu1 天前
Taro微信小程序高性能无限下拉列表实现
前端
DevRen1 天前
实现Google原生PIN码锁屏密码效果
android·前端·kotlin
ZSQA1 天前
mac安装Homebrew解决网络问题
前端
烽学长1 天前
(附源码)基于Vue的教师档案管理系统的设计与实现
前端·javascript·vue.js
前端一课1 天前
前端监控 SDK,支持页面访问、性能监控、错误追踪、用户行为和网络请求监控
前端
lee5761 天前
UniApp + SignalR + Asp.net Core 做一个聊天IM,含emoji 表情包
前端·vue.js·typescript·c#
✎﹏赤子·墨筱晗♪1 天前
Shell函数进阶:返回值妙用与模块化开发实践
前端·chrome
再学一点就睡1 天前
从 npm 到 pnpm:包管理器的进化与 pnpm 核心原理解析
前端·npm
Light601 天前
领码方案:低代码平台前端缓存与 IndexedDB 智能组件深度实战
前端·低代码·缓存·indexeddb·离线优先·ai优化
本当迷ya1 天前
openapi2ts 统一后端返回值
前端·vue.js·前端框架