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

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

一、 分片上传

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

  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,而非单纯依赖原始文件名。
相关推荐
wycode8 分钟前
Vue2源码笔记(1)编译时-模板代码如何生效之生成AST树
前端·vue.js
程序员嘉逸25 分钟前
LESS 预处理器
前端
橡皮擦19928 分钟前
PanJiaChen /vue-element-admin 多标签页TagsView方案总结
前端
程序员嘉逸32 分钟前
SASS/SCSS 预处理器
前端
咕噜分发企业签名APP加固彭于晏1 小时前
腾讯云eo激活码领取
前端·面试
子林super1 小时前
MySQL 复制延迟的排查思路
前端
CondorHero1 小时前
轻松覆盖 Element-Plus 禁用按钮样式
前端
源猿人1 小时前
nginx代理如何配置和如何踩到坑篇
前端·nginx
Captaincc1 小时前
TRAE 首场 Meetup:8月16日,期待与你在北京相聚
前端·后端·trae
vaelcy1 小时前
Cursor入门级教程,下载、安装、AI核心功能简介
前端·ai编程·cursor