前端大文件分片上传实现与断点续传方案(含完整代码讲解)

在上传大文件(如视频、安装包、模型文件)时,直接上传容易出现以下问题:

  • 文件过大 → 浏览器/服务器容易超时
  • 上传过程中断 → 重新上传浪费时间
  • 网络波动 → 上传失败率高

因此,大文件分片上传 + 断点续传 + 秒传校验 是目前最通用、最稳定的解决方案。

本文将通过一段完整可运行的示例代码,详细讲解如何在前端实现分片上传、断点续传、服务端校验等关键功能。


✨ 实现效果

  • ✔ 自动切片(默认 5MB/片,可配置)
  • ✔ 查询已上传分片(断点续传)
  • ✔ 自动跳过已上传的片段
  • ✔ 每片上传成功后重新校验
  • ✔ 所有片段上传完成后自动触发合并
  • ✔ 错误处理完善

📌 核心代码(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. 前端切片(slice 实现)

file.slice(start, end)

浏览器原生提供 slice,因此实现非常简单。

如果选择 5MB 一个片段,1GB 文件会被切成:

Math.ceil(1024MB / 5MB) = 205 片

2. 查询已上传分片(断点续传关键)

let res = await apiCheckChunks(fileId, id); let uploadedList = Array.isArray(res.data) ? res.data : [];

服务端返回的数据通常是:

[0, 3, 5, 6]

前端据此跳过已上传片段,避免重复上传,大幅提升效率。

3. 上传文件分片(FormData)

每个分片上传都附带:

  • 分片 index
  • 总分片数
  • chunk 二进制数据
  • 业务 ID 或用户 ID

这是一个完整的可追踪数据结构,支持合并校验。

4. 每片上传后重新校验(确保上传成功)

const res1 = await apiCheckChunks(fileId, id); uploadedList = res1.data || [];

避免服务器延迟导致状态不同步,确保每片上传成功。

5. 全部上传完毕 → 调用合并

await apiMergeChunks(fileId, fileName, id);

后端将所有片段按顺序合并成最终文件。

🏗 后端接口交互说明(简版)

前端需要的接口:

接口功能
apiCheckChunks(fileId)查询已上传的分片列表
apiUploadChunk(formData)上传某个片段
apiMergeChunks(fileId, fileName)合并所有片段

通常后端会在服务器临时目录中创建:

/upload/tmp/{fileId}/0 /upload/tmp/{fileId}/1 /upload/tmp/{fileId}/2 ...

然后合并成:

/upload/merged/xxx.mp4


💡 常见问题(FAQ)

1. 为什么 uploadedList.includes 报错?

通常是:

  • 服务端返回的数据不是数组
  • res.data 为 null
  • uploadedList 不是数组直接调用 includes 出错

你的代码已经做了兜底处理:

let uploadedList = Array.isArray(res.data) ? res.data : [];

但仍要保证服务端返回值格式正确。


🎯 总结

本文展示了一个完整可用的前端大文件分片上传工具方法,支持:

  • 文件切片
  • 分片校验
  • 断点续传
  • 分片上传
  • 自动合并

其优势是:

  • 前端逻辑清晰
  • 易接入任何 UI(Vue/React/uni-app)
  • 可结合后端实现秒传(加 MD5 校验)
  • 非常适合大文件上传场景

最后如何使用:

 // 父组件提交表单 调用大文件上传 addAndUpload(formData).then(async (res) => { if (res.status === 'success') { this.$message({ message: '操作成功', type: '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: (fileId, id) => checkChunks({ fileId, id }), apiUploadChunk: (formData) => uploadChunk(formData), apiMergeChunks: (fileId, fileName, id) => mergeChunks({ fileId, fileName, id }) }) this.$message.success("大文件上传完成") } catch (err) { this.$message.error("分片上传失败") console.error(err) } } this.getData(); this.resetForm2(formName); } else { this.$message({ message: res.msg, type: 'warning' }); loading.close(); } }) 

Read more

Java+Leaflet:湖南省道路长度WebGIS的构建与实践

Java+Leaflet:湖南省道路长度WebGIS的构建与实践

目录 前言 一、基础空间数据简介 1、涉及相关表 2、省域道路长度检索 二、Java后台实现 1、道路视图对象 2、Mapper空间检索查询 3、控制API实现 三、WebGIS界面实现 1、里程图例及初始化 2、各地市信息展示 四、成果展示 1、总体展示 2、分区域说明 五、总结 前言         在当今数字化时代,地理信息系统(GIS)技术在各个领域都发挥着至关重要的作用。它不仅为城市规划、交通管理、环境保护等提供了强大的技术支持,也为公众获取地理信息提供了便捷的途径。湖南省作为中国中部地区的重要省份,拥有复杂的地理环境和庞大的交通网络。如何高效地管理和展示湖南省的道路长度信息,对于交通规划、物流运输以及公众出行都具有极其重要的意义。因此,我们开展了基于Java和Leaflet的湖南省道路长度WebGIS系统的构建与实践研究。         湖南省地处中国中部,交通网络密集且复杂。随着经济的快速发展和城市化进程的加快,湖南省的道路建设不断推进,

WebToEpub:5步掌握网页小说离线阅读神器

WebToEpub:5步掌握网页小说离线阅读神器 【免费下载链接】WebToEpubA simple Chrome (and Firefox) Extension that converts Web Novels (and other web pages) into an EPUB. 项目地址: https://gitcode.com/gh_mirrors/we/WebToEpub 还在为网络小说阅读体验不佳而烦恼吗?断网无法继续追更、手机浏览器看小说耗电快、广告弹窗频繁干扰……这些问题WebToEpub都能帮您解决!这款免费的浏览器扩展能够将任何网页内容转换为标准的EPUB电子书,让您随时随地享受纯净的阅读时光。 🎯 为什么选择WebToEpub? 解决三大阅读痛点 网络依赖问题:转换后的EPUB电子书完全离线可用,再也不用担心信号问题影响阅读。 跨设备同步:生成的EPUB文件兼容所有主流电子书阅读器,包括手机、平板、Kindle等设备。 个性化定制:您可以自由编辑电子书标题、作者信息,选择需要包含的章节,甚至设置专属封面图片。

⸢ 伍-Ⅱ⸥ ⤳ 默认安全治理实践:水平越权检测 & 前端安全防控

⸢ 伍-Ⅱ⸥ ⤳ 默认安全治理实践:水平越权检测 & 前端安全防控

👍点「赞」📌收「藏」👀关「注」💬评「论」         在金融科技深度融合的背景下,信息安全已从单纯的技术攻防扩展至架构、合规、流程与创新的系统工程。作为一名从业十多年的老兵,将系统阐述数字银行安全体系的建设路径与方法论,旨在提出一套可落地、系统化、前瞻性的新一代安全架构。 序号主题内容简述1安全架构概述全局安全架构设计,描述基础框架。👉2默认安全标准化安全策略,针对已知风险的标准化防控(如基线配置、补丁管理)。3可信纵深防御多层防御体系,应对未知威胁与高级攻击(如APT攻击、零日漏洞)。4威胁感知与响应 实时监测、分析威胁,快速处置安全事件,优化第二、三部分策略。 5实战检验通过红蓝对抗演练验证防御体系有效性,提升安全水位。6安全数智化运用数据化、自动化、智能化(如AI)提升安全运营(各部分)效率。 目录 5 默认安全治理应用实践 5.2 水平越权漏洞检测 1.水平越权检测的痛点