前端如何优雅下载100G大文件?Node.js流式传输实战

💡 前端如何优雅下载100G大文件?Node.js流式传输实战

今天给大家分享一个前端下载超大文件的解决方案!工作中遇到需要下载100G大文件的场景,传统下载方式直接崩溃?来看看这个流式传输方案👇

🌟 核心思路

  1. 点击按钮先获取下载令牌(token)
  2. 通过a标签携带token访问下载接口
  3. 服务端使用流式传输(Stream)返回文件
  4. 前端边接收边保存,内存占用极低

🛠️ 前端实现

javascript 复制代码
// 下载按钮点击事件
document.getElementById('downloadBtn').addEventListener('click', async () => {
  try {
    // 1. 获取下载token
    const res = await fetch('/api/getDownloadToken', {
      method: 'POST',
      body: JSON.stringify({ filename: 'huge-file.zip' })
    });
    const { token } = await res.json();
    
    // 2. 创建隐藏的a标签触发下载
    const a = document.createElement('a');
    a.href = `/api/download?token=${token}`;
    a.download = 'huge-file.zip';
    a.style.display = 'none';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    
    console.log('下载已开始,请稍候...');
  } catch (err) {
    console.error('下载失败:', err);
  }
});

🔧 Node.js服务端代码

javascript 复制代码
const express = require('express');
const fs = require('fs');
const crypto = require('crypto');
const app = express();

// 临时存储token和文件路径的映射
const tokenMap = new Map();

app.use(express.json());

// 生成下载token
app.post('/api/getDownloadToken', (req, res) => {
  const { filename } = req.body;
  const filePath = `/data/${filename}`; // 大文件实际路径
  
  if (!fs.existsSync(filePath)) {
    return res.status(404).json({ error: '文件不存在' });
  }
  
  // 生成唯一token
  const token = crypto.randomBytes(16).toString('hex');
  tokenMap.set(token, filePath);
  
  // token有效期10分钟
  setTimeout(() => tokenMap.delete(token), 600000);
  
  res.json({ token });
});

// 流式下载文件
app.get('/api/download', (req, res) => {
  const { token } = req.query;
  const filePath = tokenMap.get(token);
  
  if (!filePath) {
    return res.status(403).send('无效或过期的token');
  }
  
  // 获取文件信息
  const stat = fs.statSync(filePath);
  const fileSize = stat.size;
  const fileName = path.basename(filePath);
  
  // 设置响应头
  res.setHeader('Content-Disposition', `attachment; filename=${fileName}`);
  res.setHeader('Content-Type', 'application/octet-stream');
  res.setHeader('Content-Length', fileSize);
  
  // 创建可读流并管道传输到响应
  const fileStream = fs.createReadStream(filePath);
  fileStream.pipe(res);
  
  // 清理token
  tokenMap.delete(token);
});

app.listen(3000, () => console.log('服务器运行中...'));

✨ 方案优势

  1. 内存友好:流式传输不占用大内存
  2. 断点续传:可通过Range头实现(进阶功能)
  3. 安全可控:token机制防止未授权下载
  4. 进度显示:前端可通过xhr监听进度(代码略)

💡 进阶优化

  • 添加下载进度条
  • 实现断点续传功能
  • 文件校验(MD5/SHA256)
  • 下载限速控制

这个方案完美解决了我们公司处理超大文件下载的痛点!大家有什么问题欢迎评论区交流~ #前端开发 #Nodejs #文件下载 #编程技巧 #web开发

相关推荐
CoolerWu35 分钟前
TRAE SOLO实战成功展示&总结:一个所见即所得的笔记软体
前端·javascript
Cassie燁42 分钟前
el-button源码解读1——为什么组件最外层套的是Vue内置组件Component
前端·vue.js
vx_bscxy32242 分钟前
告别毕设焦虑!Python 爬虫 + Java 系统 + 数据大屏,含详细开发文档 基于web的图书管理系统74010 (上万套实战教程,赠送源码)
java·前端·课程设计
北极糊的狐43 分钟前
Vue3 子组件修改父组件传递的对象并同步的方法汇总
前端·javascript·vue.js
spionbo43 分钟前
Vue3 前端分页功能实现的技术方案及应用实例解析
前端
AI绘画小331 小时前
Web 安全核心真相:别太相信任何人!40 个漏洞挖掘实战清单,直接套用!
前端·数据库·测试工具·安全·web安全·网络安全·黑客
7***n751 小时前
前端设计模式详解
前端·设计模式·状态模式
用户47949283569151 小时前
Vite 中 SVG 404 的幕后黑手:你真的懂静态资源处理吗?
前端·vite
未来之窗软件服务1 小时前
幽冥大陆(三十五)S18酒店门锁SDK go语言——东方仙盟筑基期
java·前端·golang·智能门锁·仙盟创梦ide·东方仙盟·东方仙盟sdk
卸任1 小时前
解密Flex布局:为什么flex:1仍会导致内容溢出
前端·css·flexbox