尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
断点续传(全栈)
断点续传的核心思路是不要把整个大文件一次性传完而是切成很多小块每块单独上传服务器记住“哪些块已经收到了”断了以后只补传缺的块。下面按你项目里的实现把完整过程讲一遍。一、为什么原来不行你原来的接口是这样的也就是一次 POST把整个文件塞进FormData。问题在于传 2GB 文件可能要几分钟中途网络断了、浏览器关了、服务器超时了 → 这次上传全作废只能从头再来所以断点续传必须改成 “分片 记录进度 最后合并”。二、整体流程3 步sequenceDiagram participant 浏览器 participant 后端 participant 磁盘 浏览器-浏览器: 1. 选文件生成 uploadId 浏览器-后端: 2. GET /status查已传分片 后端-磁盘: 看 .chunks/uploadId/ 里有哪些分片 后端--浏览器: 返回 [0,1,2] 已上传 loop 每个缺失分片 浏览器-后端: 3. POST /chunk传一块 5MB 后端-磁盘: 保存为 0、1、2... end 浏览器-后端: 4. POST /merge合并 后端-磁盘: 按顺序拼成完整文件 后端-磁盘: 删除临时分片 后端-数据库: 写入 FileTwo 记录 后端--浏览器: 上传成功可以把它理解成先问服务器“我传到哪了” → 只传没传完的 → 全部齐了再拼成完整文件三、前端做了什么1. 给每个文件生成唯一 IDuploadId// 用「文件名 大小 最后修改时间」算 SHA-256 const raw ${file.name}|${file.size}|${file.lastModified}; const digest await crypto.subtle.digest(SHA-256, ...);作用同一个文件不管今天传还是明天传uploadId都一样。服务器就能认出“这是同一次上传任务”。注意不是按文件内容 hash而是按元信息。内容变了但名字/大小/时间不变会当成同一次上传。对你这个场景一般够用。2. 把文件切成 5MB 一片const CHUNK_SIZE 5 * 1024 * 1024; // 5MB const totalChunks Math.ceil(file.size / CHUNK_SIZE);例如 23MB 文件 → 5 片[0,1,2,3,4]。用file.slice(start, end)从本地文件里切出每一块不用把整个文件读进内存。3. 先查状态断点的关键GET /duandianxuchuan/status?uploadIdxxxtotalChunks5 → 返回 data: [0, 1, 2] // 表示 0、1、2 已经传过了前端用Set存已传分片上传时for (let i 0; i totalChunks; i) { if (!uploadedChunks.has(i)) { // 只传缺失的分片 await uploadChunk(uploadId, i, file.slice(...)); } }这就是“断点续传”传到一半断了 → 重新选同一个文件 → status 告诉你 0、1、2 已有 → 只传 3、4。4. 全部传完后请求合并POST /duandianxuchuan/merge uploadId, fileName, totalChunks, folderId合并成功后文件才真正出现在文件列表里。5. 进度条怎么来的每传完一片就算一下percent (chunkIndex 1) / totalChunks * 100所以进度是按分片数量走的不是精确字节级但体验上够用。四、后端做了什么1. 临时分片存哪/opt/resource/file/hls2/.chunks/{uploadId}/ ├── 0 ← 第 0 片 ├── 1 ← 第 1 片 ├── 2 └── ...uploadId会先做安全校验防止路径穿越。2. status 接口遍历0到totalChunks-1看对应文件是否存在存在就加入uploaded列表返回。3. chunk 接口收到一片后Path chunkPath chunkDir.resolve(String.valueOf(chunkIndex)); if (!Files.exists(chunkPath)) { Files.copy(chunk.getInputStream(), chunkPath); }已存在就跳过 → 同一片重复传也不会出错幂等。4. merge 接口最关键检查0 ~ totalChunks-1是否都在按顺序写入最终文件try (OutputStream out Files.newOutputStream(fileSavePath)) { for (int i 0; i totalChunks; i) { Files.copy(chunkDir.resolve(String.valueOf(i)), out); } }删除.chunks/{uploadId}/临时目录像原来一样写入FileTwo表文件名、路径、大小、folderId 等五、举个具体例子假设你要传一个 12MB 的课件.pdf步骤发生了什么1浏览器算出uploadId a1b2c3...2切成 3 片0(5MB)、1(5MB)、2(2MB)3传完 0、1 后网络断了4你重新选课件.pdf上传5status 返回[0, 1]6只传分片 27merge → 生成/opt/resource/file/hls2/课件.pdf8数据库多一条记录页面刷新后能看到六、和原来接口的对比原来upload_file现在断点续传传法一次传整个文件5MB 一片一片传断了怎么办从头来接着传接口数量1 个3 个status / chunk / merge服务器临时文件无.chunks/目录入库时机传完即入库merge 成功后才入库七、几个细节多文件前端是逐个文件走完整流程每个文件有自己的uploadId。分片大小前后端都是 5MB必须一致。“已存在”检查在 merge 时做不是 chunk 时做。临时分片清理merge 成功后会删如果 merge 前一直失败.chunks会留着方便下次续传也可以以后加定时清理。八、一句话总结前端切片 后端按片存 查进度跳过已传 最后合并入库如果你愿意我还可以单独画一张「用户点上传按钮后浏览器内部函数怎么一层层调用」的流程图或者讲「如果 merge 时少了一片会怎么办」。
RELATED

相关推荐

MMORPG服务器物理模拟架构:从碰撞检测到技能判定的工程实践

MMORPG服务器物理模拟架构:从碰撞检测到技能判定的工程实践

1. 项目概述:为什么MMORPG服务器需要独立的物理模拟?做MMORPG(大型多人在线角色扮演游戏)的服务器开发,很多刚入行的朋友可能会觉得,物理模拟不就是Unity客户端里挂个Rigidbody和Collider的事儿吗&#xff…

📅 2026/8/24 8:25:05
epkg-spec2yaml与openEuler生态系统:构建现代化软件包管理的新标准

epkg-spec2yaml与openEuler生态系统:构建现代化软件包管理的新标准

epkg-spec2yaml与openEuler生态系统:构建现代化软件包管理的新标准 【免费下载链接】epkg-spec2yaml convert RPM spec to EPKG yaml 项目地址: https://gitcode.com/openeuler/epkg-spec2yaml 前往项目官网免费下载:https://ar.openeuler.org/ar…

📅 2026/8/24 8:25:05
ROS tf变换查询实战:解决Frame不存在与时间外推错误

ROS tf变换查询实战:解决Frame不存在与时间外推错误

1. 项目概述:为什么“用已发布的变换”是ROS开发者绕不开的第一道实战门槛在ROS(Robot Operating System)的实际开发中,tf(Transform Library)不是可选项,而是机器人感知与运动控制的底层神经中…

📅 2026/9/3 10:00:55
MORE NEWS

更多资讯

📰

CANN ops-math 算子调用实战:快速体验、aclnn API 与 GE 图模式全解析

CANN ops-math 算子调用实战:快速体验、aclnn API 与 GE 图模式全解析 【免费下载链接】ops-math 本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-math 本文围绕 CANN ops-math 算子库…

📰

系统提示词泄露攻防:样本反推、分层防护与落地实践

去年我们团队上线了一个客服机器人,上线第三天,群里就有人甩出一张截图——用户只用了两句话,就把我们写了三百多行的系统提示词原封不动套了出来,里面包括内部工具名、出票流程、甚至一段原本只给运营看的兜底话术。那天下午我们…

📰

协作协议:Serial Studio 仓库的 AI 结对开发工作准则

协作协议:Serial Studio 仓库的 AI 结对开发工作准则 【免费下载链接】Serial-Studio Open-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more. 项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio Serial St…

📰

OpenCloud 依赖剖析:用 Go 的 httpcc 库正确解析 HTTP Cache-Control 头

OpenCloud 依赖剖析:用 Go 的 httpcc 库正确解析 HTTP Cache-Control 头 【免费下载链接】opencloud 🌤️ OpenCloud is the open source platform for file management, sharing and collaboration. Simple and sovereign. 项目地址: https://gitcode…

📰

大模型 system prompt 泄露风险与工程化防护指南

1. 项目概述:什么是 system_prompts_leaks?它为什么突然成为技术圈高频词最近两周,“system_prompts_leaks”这个词在开发者社区、AI产品团队内部会议、甚至一线算法工程师的 Slack 频道里反复出现,不是作为学术概念,而…

📰

大促值守机器人告警风暴消噪算法:基于时序滑动窗口与拓扑剪枝

大促值守机器人告警风暴消噪算法:基于时序滑动窗口与拓扑剪枝每年大促开售前后的核心保障期,技术作战指挥室(War Room)里最让人神经衰弱的噪音,莫过于监控大盘与值班手机上疯狂响起的报警声。 当底层某个核心存储分片由…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬