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

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

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

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

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


✨ 实现效果

  • ✔ 自动切片(默认 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

ollama v0.17.0 更新:OpenClaw 一键自动安装、Web 搜索支持、全新 Context 动态分配与 Tokenizer 性能大幅优化!

2026 年 2 月 24 日,Ollama 发布了全新的 v0.17.0 版本。这一次更新可谓意义重大,不仅引入了全新的 OpenClaw 自动化集成与安装能力,还针对核心 Tokenizer 性能、VRAM 动态上下文分配、系统配置迁移逻辑、Web 搜索插件 等功能进行了深层次优化。这是一次面向 AI 模型本地化与云端融合、性能与易用性双提升的版本升级。 本文将全面解析 Ollama v0.17.0 的更新亮点、底层代码变化及其背后的设计逻辑,帮助开发者和高级用户快速理解这一版本的重要意义。 一、版本概览 版本号: v0.17.0 发布日期: 2026 年 2 月 24 日

By Ne0inhk

超酷!前端人必备的 3 个 Skills:搞定高级 UI,拿捏最佳实践,最后一个直接拉满“续航”!

最近和几位前端开发者聊天,发现一个有趣的现象:AI 写代码越来越快,但代码质量的差距反而越来越大。 有人用 Cursor 写出来的页面,一眼就能看出是 AI 生成的——紫色渐变背景、Inter 字体、千篇一律的卡片布局。而有的人用同样的工具,却能产出让人眼前一亮的作品。 差距在哪里?不在 AI 工具本身,而在于你给 AI 注入了什么样的"技能包" 。 今天想分享前端开发必备的三个 Skills。前两个是干货分享,能立刻提升你的代码质量;第三个可能出乎你的意料,但确实是我最近的真实体会。 Skill 1: 让 AI 懂设计,告别"AI 味"的界面 你有没有遇到过这种情况——AI 生成的页面虽然能用,但总觉得哪里不对劲? 布局平庸、配色单调、

By Ne0inhk

WebPShop:Photoshop完整支持WebP格式的全面解决方案

WebPShop:Photoshop完整支持WebP格式的全面解决方案 【免费下载链接】WebPShopPhotoshop plug-in for opening and saving WebP images 项目地址: https://gitcode.com/gh_mirrors/we/WebPShop WebPShop是一款专为Photoshop设计的开源插件,解决了Photoshop对WebP图像格式的兼容性问题。通过这个插件,设计师可以轻松打开、编辑和保存WebP格式图像,无论是静态图片还是动态动画,都能获得原生级别的支持。 快速配置指南 Windows系统安装步骤 1. 进入项目目录下的win文件夹 2. 双击打开WebPShop.sln解决方案文件 3. 在Visual Studio中选择x64架构进行构建 4. 将生成的插件文件复制到Photoshop插件目录即可使用 macOS系统安装指南 1. 打开项目中的mac文件夹 2. 使用Xcode打开webpshop.xcodeproj项目文件 3. 编译生成插件并安装到系统插件目录 核心功

By Ne0inhk

题解:2020-网鼎杯-青年组-Web-AreUSerialz

一、涉及知识点 序列化 serialize():将⼀个变量的数据转换为字符串。 反序列化 unserialize():将序列化后的字符串还原。 魔术方法 __destruct(析构函数):是 PHP 内置的魔术方法,核心作用是释放资源。 魔术方法 __wakeup:是 PHP 内置的魔术方法,当使用unserialize() 函数反序列化一个对象时,PHP 会自动调用该对象所属类的__wakeup方法。核心作用是:初始化反序列化对象资源,即恢复反序列化对象的状态。 二、真题解析步骤 最终目的:获得flag 1、获取源码 第一步:访问目标网站 第二步:前台界面(防御级别高,F12调试一下,不是重点) 第三步:7kscan扫描出 后台页面/子域名页面(更容易破解,重点关注) 第四步:访问后台页面/

By Ne0inhk