新闻中心
如何用Node.js实现一个支持断点续传的文件上传?
实现断点续传需前后端协同:前端切片并记录上传状态,后端存储分片并支持查询与合并;通过文件哈希标识唯一性,上传前检查已传分片以跳过重传,最后按序合并并清理临时文件。

实现支持断点续传的文件上传,核心在于将大文件分片上传,并记录已上传的片段信息,以便在网络中断或上传失败后能从中断处继续上传。Node.js结合前端可以很好地实现这一功能。以下是完整的实现思路和步骤。
1. 前端:文件切片与分片上传
用户选择文件后,前端将其切分为多个小块(chunk),并逐个上传。每个分片携带唯一标识(如文件名、文件哈希、分片序号等)。
示例代码(前端):计算文件哈希(可选,用于唯一标识文件): 可使用 spark-md5 或 FileReader 读取文件部分内容生成哈希。
切片上传逻辑:
- 读取文件,使用 File.slice() 方法切割成固定大小的块(如 1MB)
- 每块通过 POST 请求发送到服务器,附带参数:文件名、分片索引、总分片数、文件哈希等
- 上传前可先请求服务器查询已上传的分片,跳过已上传的部分
- 所有分片上传完成后,发送合并请求
2. 后端(Node.js):接收分片并存储
使用 Express 搭建服务,处理分片上传、状态查询和文件合并。
商易多用户商城
功能介绍:1. 商品出售包含拍卖模式,一口价模式。2. 全套系统采用淘宝网风格,成熟,简洁大方3. 每个商品支持多张图片上传,可自由设定,满足广大网民的迫切要求4. 商品信息支持 ubb,图文并茂5. 注册用户可参与竞拍,或者拍卖自己的商品6. 拥有会员注册,交易提醒,成交商品确认等邮件发送功能7. 拥有交易双方信用评价的功能,使得交易安全可*,可信度高8. 拥有安全稳定的用户虚拟币平台,可实现商
0
查看详情
所需依赖:
express、multer(处理 multipart/form-data)、fs、path
关键接口设计:- /upload/check:查询某文件已上传的分片列表
- /upload/chunk:接收单个分片,保存到临时目录
- /upload/merge:所有分片上传完成后,合并文件
示例代码(Node.js 后端):
const express = require('express');
const multer = require('multer');
const fs = require('fs');
const path = require('path');
const app = express();
const uploadDir = './uploads';
const chunkDir = './chunks';
!fs.existsSync(uploadDir) && fs.mkdirSync(uploadDir);
!fs.existsSync(chunkDir) && fs.mkdirSync(chunkDir);
// 配置 multer 存储分片
const storage = multer.diskStorage({
destination: (req, file, cb) => {
const dir = path.join(chunkDir, req.body.fileHash);
!fs.existsSync(dir) && fs.mkdirSync(dir, { recursive: true });
cb(null, dir);
},
filename: (req, file, cb) => {
// 使用分片索引命名
cb(null, `part-${req.body.chunkIndex}`);
}
});
const upload = multer({ storage });
// 查询已上传的分片
app.post('/upload/check', (req, res) => {
const { fileHash } = req.body;
const chunkPath = path.join(chunkDir, fileHash);
if (!fs.existsSync(chunkPath)) return res.json({ uploaded: [] });
fs.readdir(chunkPath, (err, files) => {
if (err) return res.status(500).send();
const uploaded = files.map(f => parseInt(f.split('-')[1]));
res.json({ uploaded });
});
});
// 接收分片
app.post('/upload/chunk', upload.single('chunk'), (req, res) => {
res.json({ success: true });
});
// 合并文件
app.post('/upload/merge', (req, res) => {
const { fileHash, fileName, totalChunks } = req.body;
const chunkPath = path.join(chunkDir, fileHash);
const filePath = path.join(uploadDir, fileName);
const writeStream = fs.createWriteStream(filePath);
function appendChunk(i) {
if (i >= totalChunks) {
writeStream.end();
// 清理分片
fs.rm(chunkPath, { recursive: true }, () => {});
return res.json({ url: `/files/${fileName}` });
}
const partPath = path.join(chunkPath, `part-${i}`);
const readStream = fs.createReadStream(partPath);
readStream.pipe(writeStream, { end: false });
readStream.on('end', () => appendChunk(i + 1));
}
appendChunk(0);
});
3. 断点续传的关键逻辑
要真正实现“续传”,需满足以下几点:
- 唯一标识文件:使用文件名 + 大小 + 哈希值确保文件唯一性
- 上传前检查:上传开始前调用 /upload/check 获取已上传的分片,跳过重传
- 按序存储分片:每个分片以索引命名,便于后续合并
- 合并后清理临时文件:防止磁盘占用
4. 前端优化建议
- 使用 Web Workers 计算大文件哈希,避免阻塞 UI
- 添加上传进度条:基于已上传分片数量 / 总数
- 支持暂停/恢复:暂停时停止发送,恢复时重新 check 并继续
- 错误重试机制:对失败的分片进行有限次重试
以上就是如何用Node.js实现一个支持断点续传的文件上传?的详细内容,更多请关注其它相关文章!
# 前端
# 跳过
# 文件上传
# 多用户
# 断点续传
# 上传
# 分片
# 前端优化
# 后端
# app
# node
# json
# node.js
# js
# stream
# 医疗网站建设昆明
# 如何建设房地产网站
# 南京推广网站推广费
# 雨湖区商城网站建设招标
# 农业门户网站建设方案
# 关键词越刷越没有排名
# 商业网站建设接单
# seo的用法
# 智能门店营销推广策略
# seo关键词挖掘流程
# 服务端
# 如何使用
# 如何用
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
如何在复杂的电商平台中优雅地管理共享资源并确保正确重定向,使用spryker-shop/resource-share-page模块助你一臂之力
优化 Jest 模拟:强制未实现函数抛出错误以提升测试效率
c++ 获取系统当前时间 c++时间戳获取方法
Win11蓝牙耳机断连怎么解决 Win11蓝牙设置重新配对与驱动更新【技巧】
4399网页游戏电脑版全新入口 4399电脑端在线玩指南
qq邮箱日历功能怎么用_创建日程与会议邀请的技巧
Typer应用中动态命令行参数的解析与处理
魅族20怎样在浏览器开无图省流_iPhone魅族20浏览器开无图省流【流量节省】
Basecamp怎样用留言钉固定重点_Basecamp用留言钉固定重点【重点标记】
Win11怎么设置鼠标主按键_Win11鼠标左右键功能互换
修复二维数组索引越界异常:一维循环到二维坐标的正确映射
不会效仿卡普空!《铁拳》制作人澄清:不采取赛事付费|直播|
Go语言中高效处理x-www-form-urlencoded表单数据
冬*霸灯泡不亮怎么办_浴霸取暖灯一盏不亮的灯座清洁修复法
火狐浏览器占用内存高卡顿怎么办 火狐浏览器性能优化设置技巧
双系统安装时,如何设置默认启动系统? msconfig命令了解一下!
J*aScript类型检查_j*ascript代码规范
谷歌google账号怎么注册账号 谷歌账号注册官方流程
魅族17怎样用浏览器译外语网页_iPhone魅族17浏览器译外语网页【即时翻译】
在React函数组件中利用原生HTML5进行邮箱地址验证
邮编格式怎么匹配地址_根据邮编格式快速匹配详细地址的技巧
J*aScript生成器_j*ascript异步迭代
Tabulator表格中精确实现日期时间排序的指南
sublime怎么覆盖插件的默认快捷键_sublime快捷键优先级与设置
如何使用Node.js csv 包按条件移除含空字段的CSV记录
VS Code远程开发时如何处理文件权限问题
极速漫画官方主页网址 极速漫画漫画在线浏览官网链接
内存疯狂猛猛涨价:主板销量直接腰斩!
高德地图沿途添加点失败如何解决 高德多点规划方法
AO3中文官网链接_AO3网页版稳定镜像站
微博网页版直接访问 微博网页版账号管理快速入口
css链接悬停下划线样式如何自定义_使用::after结合content和transition
漫蛙漫画网页端入口 漫蛙2官方正版漫画站点
《刺客信条:影》PS5 Pro和Switch 2画面对比
深入理解Google Cloud Datastore查询:祖先路径与数据一致性
PPT平滑切换怎么做 PPT炫酷“平滑”切换动画制作教程【必学】
知乎APP怎么管理已购盐选内容_知乎APP盐选内容购买记录与查看方法
qq游戏网页版直接玩_qq游戏免下载快速入口
京东京造J1和网易云音乐氧气真无线有什么不同_国产电商蓝牙耳机音质对比
qq游戏手机版下载安装_qq游戏移动端入口
Go语言中JSON数据解析与字段访问教程
React Router 嵌套组件中 URL 重定向问题的解决方案
响应式CSS Grid布局:优化网格项在小屏幕下的堆叠与宽度适配
GemBox Document HTML转PDF垂直文本渲染问题及解决方案
痛风发作了怎么办? 快速止痛和后期饮食调理
TypeScript/J*aScript:高效查找数组中首个唯一ID对象
CSS子选择器:如何区分并样式化嵌套列表的子层级
Win10桌面图标出现小盾牌怎么办 Win10去除UAC图标教程【解决】
Golang并发任务中错误如何聚合_Golang goroutine error收集方式
如何在 Excel Online 和 Google 表格中更改日期格式


2025-10-10
浏览次数:次
返回列表