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

容器化Fastify Node.js服务器:如何将流生成文件下载到用户本地

解决Fastify流式文件下载到客户端的问题

你的核心问题是当前代码将压缩后的文件写入了Docker容器的本地文件系统,而非直接将流返回给客户端。Fastify可以直接通过响应流将内容发送给用户,无需先写入本地文件。

修改方案

直接将压缩后的流通过Fastify的响应对象返回,同时设置正确的HTTP头让客户端识别为下载文件:

'use strict'
const path = require('node:path');
const fs = require('node:fs');
const { pipeline } = require('node:stream/promises');
const zlib = require('zlib');

module.exports = async function(fastify, opts) {
  fastify.get('/', async function(request, reply) {
    // 设置下载相关的响应头
    reply.header('Content-Disposition', 'attachment; filename="zipped.json.gz"');
    reply.header('Content-Type', 'application/gzip');

    const readStream = fs.createReadStream(path.join(path.dirname(__dirname), 'package.json'));
    const gzipStream = zlib.createGzip();

    try {
      // 将可读流 -> gzip压缩流 -> 响应流
      await pipeline(
        readStream,
        gzipStream,
        reply.raw // 使用reply.raw直接操作底层HTTP响应流
      );
      // pipeline完成后无需额外返回,因为响应已经发送
    } catch (err) {
      fastify.log.error('pipeline failed', err.message);
      // 若出错,确保响应状态码设置为500
      reply.code(500).send('Download failed');
    }
  });
}

关键说明

  • 移除容器本地可写流:不再需要fs.createWriteStream,直接将压缩后的流导向客户端响应
  • 设置响应头:
    • Content-Disposition:告诉客户端这是一个附件,指定下载后的文件名
    • Content-Type:对应gzip文件的MIME类型
  • 使用reply.raw:Fastify的reply.raw是底层的HTTP响应流,可以直接作为pipeline的目标,确保流式传输

测试curl命令

运行服务器后,用以下命令将文件下载到本地:

curl http://your-server-address/ -o zipped.json.gz

这样就能直接将压缩后的文件保存到你的本地文件系统,而非Docker容器内。

内容的提问来源于stack exchange,提问作者Curtis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:52:29