You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Node.js核心模块实现用户从服务器下载文件?

使用Node.js核心模块实现文件下载服务

基础实现(http + fs模块)

借助Node.js的http和fs核心模块就能快速实现文件下载服务,核心思路是创建HTTP服务器,当用户请求指定文件时,读取文件并通过响应流返回给客户端,同时设置正确的响应头触发浏览器的下载行为。

示例代码:

const http = require('http');
const fs = require('fs');
const path = require('path');

const server = http.createServer((req, res) => {
  // 可根据请求路径动态调整要下载的文件路径
  const filePath = path.join(__dirname, 'target-file.pdf');

  // 检查文件是否存在
  fs.access(filePath, fs.constants.F_OK, (err) => {
    if (err) {
      res.writeHead(404, { 'Content-Type': 'text/plain' });
      res.end('文件不存在');
      return;
    }

    // 获取文件信息,用于设置响应头的文件大小
    fs.stat(filePath, (statErr, stats) => {
      if (statErr) {
        res.writeHead(500, { 'Content-Type': 'text/plain' });
        res.end('读取文件信息失败');
        return;
      }

      // 设置响应头触发下载行为
      res.writeHead(200, {
        'Content-Type': 'application/octet-stream', // 通用二进制类型,兼容多数文件格式
        'Content-Disposition': `attachment; filename="downloaded-file.pdf"`, // 指定下载后的文件名
        'Content-Length': stats.size
      });

      // 创建文件读取流,流式传输避免大文件占满内存
      const fileStream = fs.createReadStream(filePath);
      // 将文件流管道到响应对象
      fileStream.pipe(res);

      // 处理流读取错误
      fileStream.on('error', (streamErr) => {
        res.writeHead(500, { 'Content-Type': 'text/plain' });
        res.end('读取文件出错');
      });
    });
  });
});

const PORT = 3000;
server.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
});

关键细节说明

  • 响应头配置:
    • Content-Disposition: attachment 是触发浏览器下载的核心设置,filename 定义用户下载后看到的文件名;若想让浏览器直接预览文件(如图片、文本),可将attachment替换为inline。
    • Content-Type 建议根据文件实际类型设置(如image/png、text/plain),不确定类型时用application/octet-stream通用类型。
    • Content-Length 告知浏览器文件总大小,方便显示下载进度。
  • 流式传输优势:使用fs.createReadStream而非fs.readFile,后者会将整个文件加载到内存,大文件场景下易导致内存溢出;流式传输分块发送数据,内存占用更稳定。
  • 安全与错误处理:必须处理文件不存在、读取失败等异常,避免服务器崩溃;若支持动态文件路径,需校验请求路径防止目录遍历攻击(如用path.normalize限制文件在指定目录内)。

动态文件下载(根据URL路径匹配)

若需支持用户通过不同URL下载不同文件,可解析请求URL动态确定文件路径:

// 在createServer回调中修改文件路径逻辑
const requestedFileName = req.url.slice(1); // 假设请求URL为 /report.xlsx,此处获取report.xlsx
const allowedDir = path.join(__dirname, 'downloads');
const filePath = path.join(allowedDir, requestedFileName);

// 校验路径是否在允许的目录内,防止目录遍历
if (!filePath.startsWith(allowedDir)) {
  res.writeHead(403, { 'Content-Type': 'text/plain' });
  res.end('无权访问该文件');
  return;
}

// 后续文件读取、响应逻辑同基础实现

内容的提问来源于stack exchange,提问作者Yeshwanth. 061

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 03:15:57