流式文件(下载)
原创2026/3/5大约 1 分钟
有时你可能希望将文件从 REST API 发送回客户端。 要使用 Nest 做到这一点,通常你需要执行以下操作
import { Controller, Get, Res } from '@nestjs/common'
import { UserService } from './user.service'
import { join } from 'path'
import { createReadStream } from 'fs'
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
async findOne(@Res() res: any) {
const file = createReadStream(join(process.cwd(), 'package.json'))
file.pipe(res)
}
}但这样做你最终会失去对后控制器拦截器逻辑的访问权限。 要处理此问题,你可以返回一个 StreamableFile 实例,在后台,框架将负责管道响应
StreamableFile 是一个保留要返回的流的类。 要创建新的 StreamableFile,你可以将 Buffer 或 Stream 传递给 StreamableFile 构造函数。
import { Controller, Get, StreamableFile } from '@nestjs/common'
import { UserService } from './user.service'
import { join } from 'path'
import { createReadStream } from 'fs'
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
findOne(): StreamableFile {
const file = createReadStream(join(process.cwd(), 'package.json'))
return new StreamableFile(file)
}
}默认的内容类型是 application/octet-stream,如果你需要自定义响应你可以使用 res.set 方法或者 @Header() 装饰器,像这样:
import { Controller, Get, Header, StreamableFile } from '@nestjs/common'
import { UserService } from './user.service'
import { join } from 'path'
import { createReadStream } from 'fs'
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
@Header('Content-Type', 'application/json')
@Header('Content-Disposition', 'attachment; filename="package.json"')
findOne(): StreamableFile {
const file = createReadStream(join(process.cwd(), 'package.json'))
return new StreamableFile(file)
}
}访问http://localhost:3000/user,就会直接将文件下载下来了,并且,在@Header()装饰器里设置了文件名为:package.json
至此,本章节的学习就到此结束了,如有疑惑,可对接技术客服进行相关咨询。