目录
文件流式传输
note
本章介绍如何从您的 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
实例,在底层,框架将负责管道化响应。
StreamableFile 类
StreamableFile
是一个保存即将返回的流的类。要创建一个新的 StreamableFile
,您可以将 Buffer 或 Stream 传递给 StreamableFile
构造函数。
tip
可以从 @nestjs/common
导入 StreamableFile
类。
跨平台支持
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
方法或 @Header()
装饰器,如下所示:
import { Controller, Get, StreamableFile, Res, Header } from '@nestjs/common';
import { createReadStream } from 'fs';
import { join } from 'path';
import type { Response } from 'express';
@Controller('file')
export class FileController {
@Get()
getFile(@Res({ passthrough: true }) res: Response): 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);
}
// 或者甚至:
@Get()
@Header('Content-Type', 'application/json')
@Header('Content-Disposition', 'attachment; filename="package.json"')
getStaticFile(): StreamableFile {
const file = createReadStream(join(process.cwd(), 'package.json'));
return new StreamableFile(file);
}
}