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

如何在Node.js/Express.js中后台发送文件并解决下载超时问题

解决大文本文件下载超时问题

听起来你遇到了大文件下载因超时而失败的麻烦,尤其是下载前还要做文件处理,确实容易触发30秒的超时限制。针对文本文件的场景,我给你几个实用的解决方案:

1. 改用流式传输(最推荐)

res.download()是一次性把整个文件读取到内存后再发送,大文件不仅容易触发超时,还会占用大量服务器内存。文本文件非常适合用流式传输——把文件拆成小块分开发送,每一块的传输都不会超过30秒,从根本上避免超时问题。

修改后的代码示例:

const fs = require('fs');

app.get('/download', async (req, res) => {
  try {
    // 先执行文件预处理,如果censor是异步函数记得加await
    await censor(filePath); 

    // 设置下载相关的响应头
    res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
    res.setHeader('Content-Type', 'text/plain'); // 根据你的文本类型调整,比如text/csv、text/markdown等

    // 创建文件流并通过管道发送给响应对象
    const fileStream = fs.createReadStream(filePath);
    fileStream.pipe(res);

    // 处理流传输中的错误
    fileStream.on('error', (err) => {
      console.error('文件流传输错误:', err);
      res.status(500).send('下载失败,请稍后重试');
    });

    // 监听下载完成事件(可选)
    res.on('finish', () => {
      console.log(`文件 ${fileName} 下载完成`);
    });
  } catch (err) {
    console.error('预处理或下载出错:', err);
    res.status(500).send('服务器内部错误');
  }
});

2. 优化前置处理censor()函数

如果censor()处理大文本文件耗时过长,会直接导致下载请求还没开始发送就超时。你可以这样优化:

  • 把censor()改成异步非阻塞的方式,避免卡住整个请求进程
  • 提前预处理文件并缓存结果:比如用户请求前就完成文件处理,或者第一次处理后把结果存在缓存目录,后续请求直接用缓存好的文件,不用重复执行处理逻辑
  • 如果处理逻辑复杂,考虑用Node.js的Worker Threads来单独处理,不占用主进程的时间

3. 调整超时配置(治标方案)

如果流式传输仍有问题,可能是你的服务器或反向代理(比如Nginx、PM2)设置了30秒的超时限制,可以针对性调整:

  • Express本身:在路由里添加req.setTimeout(60000)把请求超时延长到60秒(根据需求调整时长)
  • Nginx:修改proxy_read_timeout和proxy_send_timeout参数,延长反向代理的超时时间

不过这只是临时缓解方案,流式传输才是适合大文件下载的长期解决办法。

内容的提问来源于stack exchange,提问作者MAZHAR ALI BAIG

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:29:09