跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScript大前端

前端大文件分片上传与断点续传实战方案

大文件上传常遇超时或中断风险,分片上传结合断点续传是稳定方案。核心流程包括前端切片、服务端校验已传分片、逐片上传及最终合并。代码示例展示了基于 FormData 的分片逻辑与错误处理机制,支持自动跳过已完成片段并重新校验状态,确保数据完整性。后端需配合临时存储与合并接口,前端则需适配不同框架环境。

全栈工匠发布于 2026/4/5更新于 2026/7/2934 浏览

前端大文件分片上传与断点续传实战方案

在处理视频、安装包或模型文件等大资源时,直接全量上传往往面临浏览器超时、网络波动导致中断以及重传耗时等问题。采用分片上传 + 断点续传 + 服务端校验是目前最稳健的解决方案。

核心实现逻辑

下面是一个完整的前端工具函数 uploadLargeFile,它封装了切片、校验、上传及合并的核心流程。

export async function uploadLargeFile({ 
  file, 
  fileId, 
  id, 
  chunkSize = 5 * 1024 * 1024, 
  apiCheckChunks, 
  apiUploadChunk, 
  apiMergeChunks 
}) {
  if (!file) throw new Error("file 不能为空");
  if (!fileId) throw new Error("fileId 不能为空");

  const fileName = file.name;
  const totalChunks = Math.ceil(file.size / chunkSize);
  const chunks = [];

  // 1. 前端文件切片
  for (let i = 0; i < totalChunks; i++) {
    const start = i * chunkSize;
    const end = Math.min(file.size, start + chunkSize);
    chunks.push(file.slice(start, end));
  }

  // 2. 查询已上传分片(断点续传关键)
  let res = await apiCheckChunks(fileId, id);
  let uploadedList = Array.isArray(res.data) ? res.data : [];
  if (!Array.isArray(uploadedList)) uploadedList = [];

  // 3. 逐片上传
  for (let i = 0; i < totalChunks; i++) {
    if (uploadedList.includes(i)) {
      console.log(`分片 ${i} 已上传,跳过`);
      continue;
    }

    const formData = new FormData();
    formData.append("fileId", fileId);
    formData.append("id", id);
    formData.append("chunkIndex", i);
    formData.append("totalChunks", totalChunks);
    formData.append("chunk", chunks[i]);

    await apiUploadChunk(formData);

    // 上传成功后重新查询列表,确保状态同步
    const res1 = await apiCheckChunks(fileId, id);
    uploadedList = res1.data || [];
    
    if (!uploadedList.includes(i)) {
      throw new Error(`分片 ${i} 上传失败,请重试`);
    }
  }

  // 4. 所有片段上传完成 → 执行合并
  if (uploadedList.length === totalChunks) {
    console.log("所有分片上传完成,开始合并文件");
    await apiMergeChunks(fileId, fileName, id);
  } else {
    throw new Error("未上传完所有分片,无法合并");
  }

  return true;
}

关键步骤解析

1. 文件切片

利用浏览器原生的 file.slice(start, end) 方法即可轻松实现。例如设置 5MB 为一片,1GB 的文件会被切分为约 205 个片段。这种方式对内存友好且无需额外库支持。

2. 断点续传机制

这是提升用户体验的关键。在正式上传前,先调用接口查询服务端已存在的分片索引(如 [0, 3, 5])。前端遍历本地切片时,若索引存在于列表中则直接跳过,避免重复传输。

3. 分片上传与校验

每个分片通过 FormData 发送,携带 fileId、chunkIndex 等元数据。为了应对服务器处理延迟,代码在每片上传后再次查询已上传列表。这种'乐观上传 + 实时校验'的策略能有效防止因网络抖动导致的文件损坏。

4. 文件合并

当所有分片确认上传完毕后,通知后端将临时目录下的碎片按顺序合并为最终文件。后端通常会在 /upload/tmp/{fileId}/ 下管理碎片,合并后移至正式存储路径。

后端接口规范

前端主要依赖以下三个接口进行交互:

接口功能说明
apiCheckChunks(fileId, id)查询当前任务已上传的分片索引列表
apiUploadChunk(formData)上传单个分片二进制数据
apiMergeChunks(fileId, fileName, id)触发后端合并操作

常见问题排查

Q: uploadedList.includes 报错怎么办? 这通常是因为服务端返回的数据格式不符合预期(如 null 或非数组)。代码中已做兜底处理 Array.isArray(res.data) ? res.data : [],但建议后端严格保证返回结构一致。

集成示例

在实际项目中,该函数可嵌入到表单提交逻辑中。以下是一个基于 Vue 环境的调用示意:

// 父组件提交表单时调用
addAndUpload(formData).then(async (res) => {
  if (res.status === 'success') {
    this.$message.success('操作成功');
    this.file_Id = res.data.fileId;
    loading.close();
    this.dialogVisible = false;

    if (this.upFile !== null) {
      const fileId = this.file_Id;
      const file = this.upFile;
      
      this.$message.info("大文件,启动分片上传...");
      try {
        await uploadLargeFile({
          file,
          fileId,
          id: res.data.id,
          chunkSize: 20 * 1024 * 1024,
          apiCheckChunks: (fid, iid) => checkChunks({ fileId: fid, id: iid }),
          apiUploadChunk: (fd) => uploadChunk(fd),
          apiMergeChunks: (fid, fname, iid) => mergeChunks({ fileId: fid, fileName: fname, id: iid })
        });
        this.$message.success("大文件上传完成");
      } catch (err) {
        this.$message.error("分片上传失败");
        console.error(err);
      }
    }
    this.getData();
    this.resetForm2(formName);
  } else {
    this.$message.warning(res.msg);
    loading.close();
  }
});

该方案逻辑清晰,易于接入 Vue、React 或 uni-app 等不同 UI 框架。结合 MD5 校验还可进一步扩展秒传功能,非常适合企业级大文件上传场景。

目录

  1. 前端大文件分片上传与断点续传实战方案
  2. 核心实现逻辑
  3. 关键步骤解析
  4. 1. 文件切片
  5. 2. 断点续传机制
  6. 3. 分片上传与校验
  7. 4. 文件合并
  8. 后端接口规范
  9. 常见问题排查
  10. 集成示例
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Z-Image-Turbo 对比 Stable Diffusion 核心优势解析
  • Linux C/C++ 编译参数详解:-I, -l, -L
  • jsPDF 中文显示解决方案:字体引入与配置指南
  • Linux 常用命令汇总
  • 微信历史版本下载地址及关闭自动更新方法
  • MHT-MD761 与云影无人机的集成实操要点,硬件安装与接口对接
  • CoPaw 个人助理部署与定制指南:从本地到飞书接入
  • 边缘计算:重塑医疗领域未来的关键力量
  • 以太网网口与 PHY 芯片硬件设计详解
  • 微信接入 OpenClaw 开源 AI 智能体框架
  • Python ezdxf 库:DXF 文件处理入门与实战
  • Qwen2.5-7B 与 Stable Diffusion 多模态协同部署实战
  • 大模型应用:如何指导 Agent 像人一样思考及思维链范式解析
  • Java 泛型:编译期类型安全与实战应用
  • 基于 YOLOv8 的无人机红外可见光光伏缺陷检测数据集与训练指南
  • 锐龙 AI 7 H 350和锐龙 7 H255对比评测
  • 基于 Ollama 的本地私有大模型部署与调用指南
  • Copilot Cowork 核心逻辑解析:基于 Kotlin 构建 AI Agent
  • DeepSeek 与通义万相结合制作 AI 视频实战指南
  • 在 Cursor 中配置 MCP 服务实现自动化开发

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online