Nest.js 流式传输文件

注意 本章介绍如何从 HTTP 应用程序流式传输文件。 下面给出的示例不适用于 GraphQL 或微服务应用程序。

有时我们可能希望将文件从 REST API 发送回客户端。 要使用 Nest 执行此操作,通常会执行以下操作:

@Controller('file')
export class FileController {
  @Get()
  getFile(@Res() res: Response) {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    file.pipe(res);
  }
}

但是这样做你最终会失去对你的后控制器拦截器逻辑的访问。 为了处理这个问题,你可以返回一个 StreamableFile 实例,并且在底层,框架将负责处理响应。

Streamable File 类

StreamableFile 是一个保存要返回的流的类。 要创建新的 StreamableFile,我们可以将 Buffer 或 Stream 传递给 StreamableFile 构造函数。

StreamableFile 类可以从@nestjs/common 导入。

跨平台支持

默认情况下,Fastify 可以支持发送文件,无需调用 stream.pipe(res) ,所以你根本不需要使用 StreamableFile 类。 但是,Nest 支持在这两种平台类型中使用 StreamableFile,因此如果我们最终在 Express 和 Fastify 之间切换,则无需担心两种引擎之间的兼容性。

示例

可以在下面找到一个将 package.json 作为文件而不是 JSON 返回的简单示例,但这个想法自然地扩展到图像、文档和任何其他文件类型。

import { Controller, Get, StreamableFile } from '@nestjs/common';
import { createReadStream } from 'fs';
import { join } from 'path';

@Controller('file')
export class FileController {
  @Get()
  getFile(): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    return new StreamableFile(file);
  }
}

默认内容类型是 application/octet-stream ,如果需要自定义响应可以使用 res.set 方法。

import { Controller, Get, StreamableFile, Response } from '@nestjs/common';
import { createReadStream } from 'fs';
import { join } from 'path';

@Controller('file')
export class FileController {
  @Get()
  getFile(@Response({ passthrough: true }) res): StreamableFile {
    const file = createReadStream(join(process.cwd(), 'package.json'));
    res.set({
      'Content-Type': 'application/json',
      'Content-Disposition': 'attachment; filename="package.json"',
    });
    return new StreamableFile(file);
  }
}

查看笔记

扫码一下
查看教程更方便