如何用Node.js实现一个支持断点续传的文件上传?


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

如何用node.js实现一个支持断点续传的文件上传?

实现支持断点续传的文件上传,核心在于将大文件分片上传,并记录已上传的片段信息,以便在网络中断或上传失败后能从中断处继续上传。Node.js结合前端可以很好地实现这一功能。以下是完整的实现思路和步骤。

1. 前端:文件切片与分片上传

用户选择文件后,前端将其切分为多个小块(chunk),并逐个上传。每个分片携带唯一标识(如文件名、文件哈希、分片序号等)。

示例代码(前端):

计算文件哈希(可选,用于唯一标识文件): 可使用 spark-md5FileReader 读取文件部分内容生成哈希。

切片上传逻辑:

  • 读取文件,使用 File.slice() 方法切割成固定大小的块(如 1MB)
  • 每块通过 POST 请求发送到服务器,附带参数:文件名、分片索引、总分片数、文件哈希等
  • 上传前可先请求服务器查询已上传的分片,跳过已上传的部分
  • 所有分片上传完成后,发送合并请求

2. 后端(Node.js):接收分片并存储

使用 Express 搭建服务,处理分片上传、状态查询和文件合并。

Facetune Facetune

一款在线照片和视频编辑工具,允许用户创建AI头像

Facetune 109 查看详情 Facetune 所需依赖:

expressmulter(处理 multipart/form-data)、fspath

关键接口设计:
  • /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 负责接收、存储和合并,前端负责切片和流程控制。不复杂但容易忽略细节,比如文件哈希一致性、并发写入等问题。

以上就是如何用Node.js实现一个支持断点续传的文件上传?的详细内容,更多请关注其它相关文章!


# 前端  # 如何用  # 跳过  # 文件上传  # 断点续传  # 上传  # 分片  # 前端优化  # 后端  # app  # node  # json  # node.js  # js  # stream  # 河南seo排名哪个好点  # 和平区互联网推广营销  # seo机构营销方案优化  # 面粉行业推广营销策划  # 秭归建设信息网站首页  # 营销推广活动流程表格  # 网站优化和带宽有关系吗  # 贵溪上门网站建设哪家好  # 彩妆网店营销与推广方案  # 滦南抖音seo哪家好  # 临时文件  # 重试  # 鼠标 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: HTML与J*aScript实现下拉菜单驱动的动态表格:构建交互式维修表单  海棠阅读登录教程_详细讲解海棠登录操作  Bootstrap 5导航栏折叠功能失效:数据属性迁移指南  抖音网页版地址直接进入_抖音网页版在线观看入口  苹果手机怎么合并照片_苹果手机合并多张照片的操作方法  如何在CSS中使用过渡制作按钮边框渐变_border-color transition实现  如何在vscode中关闭it环境  Golang如何操作指针参数_Go pointer参数传递规则  谷歌浏览器官方镜像获取方法_谷歌浏览器网页版入口极速直达  使用AI在VS Code中将代码从一种语言翻译成另一种  抖音视频如何添加标题?添加标题有哪些好处?  CDR如何复制交互式填充色  如何发挥新媒体矩阵作用?新媒体矩阵怎么搭建?  J*aScript中高效处理用户输入:从Keyup事件到表单提交的优化实践  sublime如何自定义文件类型图标_AFileIcon插件的主题切换与个性化配置  b站怎么用微信登录_b站微信登录方法  《王者荣耀世界》英雄获取攻略  惠普电脑BIOS界面看不懂怎么办_HP电脑BIOS功能选项解读与设置  第五人格PC版怎么避免被封号_第五人格PC版防封号注意事项  毒蘑菇VOLUMESHADER_BM官网首页登录入口 毒蘑菇VOLUMESHADER_BM官网首页登录入口说明  5G和6G的连接密度有什么区别 6G每平方公里能连接多少设备  QQ网页版入口导航 QQ网页版在线访问通道  发布小红书怎么屏蔽粉丝?屏蔽粉丝能看到吗?  12306夜间购票失败? | 查看官方公布的暂停服务公告与应对方案  在Dash应用中自定义HTML标题和网站图标  青橙手机语音助手怎么唤醒_青橙手机语音助手设置与唤醒方法  CSS过渡如何实现按钮悬停效果_transition属性控制背景颜色变化  Linux如何开发轻量级数据服务模块_Linux服务化设计  mysql镜像配置如何恢复数据_mysql镜像配置数据恢复详细流程  Composer reinstall命令重装损坏的包  百度网盘网页入口链接分享 百度网盘官网入口网页登录  《偃武》甘宁技能详解  荣耀Magic6 Pro拍照成像偏暗_荣耀Magic6 Pro夜景优化  食品生产用水只要符合国家规定的生活饮用水卫生标准就可以吗  支付宝网页版在线入口 支付宝官网电脑登录入口  163邮箱网页版入口 163邮箱在线使用  t3出行如何使用微信支付  J*aScript文本高亮功能优化:解决多词匹配错误与精确分割策略  AI图层蒙版怎么用_AI图层蒙版应用技巧与设计实例  抖音号怎么解除企业认证改成个人?改成个人有影响吗?  《糖豆》添加舞曲方法  sublime如何配置PHP开发环境_在sublime中运行与调试PHP代码  《i莞家》修改昵称方法  Highcharts雷达图轴线交点数值标注指南  todesk如何添加信任设备_todesk信任设备设置教程  4399小游戏下装链接 4399小游戏下载链接入口  外媒评《燕云十六声》DIY载具新玩法:很像《塞尔达传说王国之泪》!  PHP页面重载后变量状态保持:实现用户档案连续浏览的教程  Win11如何分屏操作_Win11多窗口分屏技巧  微信如何设置字体大小_微信字体设置的阅读舒适 

 2025-10-10

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.