javascript - 如何从 Controller 返回 PDF 文件

标签 javascript node.js nestjs

我正在尝试使用 NestJs 从 Controller 端点返回 PDF 文件。当不设置 Content-type header 时,getDocumentFile 返回的数据会很好地返回给用户。然而,当我添加 header 时,我得到的返回似乎是某种奇怪形式的 GUID,响应总是如下所示: xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 其中 x 是小写十六进制字符。它似乎也与处理函数的实际返回值完全无关,因为我什至在根本不返回任何内容时得到这个奇怪的 GUID 东西。

当不设置Content-type: application/pdf时,该函数可以很好地返回缓冲区的数据,但是我需要设置 header 以使浏览器将响应识别为一个对我的用例很重要的 PDF 文件。

Controller 看起来像这样:

@Controller('documents')
export class DocumentsController {
  constructor(private documentsService: DocumentsService) {}

  @Get(':id/file')
  @Header('Content-type', 'application/pdf')
  async getDocumentFile(@Param('id') id: string): Promise<Buffer> {
    const document = await this.documentsService.byId(id)
    const pdf = await this.documentsService.getFile(document)

    // using ReadableStreamBuffer as suggested by contributor
    const stream = new ReadableStreamBuffer({
      frequency: 10,
      chunkSize: 2048,
    })
    stream.put(pdf)
    return stream
  }
}

我的 DocumentsService 像这样:

@Injectable()
export class DocumentsService {
  async getAll(): Promise<Array<DocumentDocument>> {
    return DocumentModel.find({})
  }

  async byId(id: string): Promise<DocumentDocument> {
    return DocumentModel.findOne({ _id: id })
  }

  async getFile(document: DocumentDocument): Promise<Buffer> {
    const filename = document.filename
    const filepath = path.join(__dirname, '..', '..', '..', '..', '..', 'pdf-generator', 'dist', filename)

    const pdf = await new Promise<Buffer>((resolve, reject) => {
      fs.readFile(filepath, {}, (err, data) => {
        if (err) reject(err)
        else resolve(data)
      })
    })
    return pdf
  }
}

我最初只是返回缓冲区(return pdf),但这带来了与上述尝试相同的结果。在 NestJs 的存储库上,一位用户建议使用上述方法,这显然对我来说也不起作用。请参阅 GitHub 线程 here .

最佳答案

2021 年更新:

从现在开始,在 Nest 版本 8 中,您可以使用类 StreamableFile:

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);
  }
}

官方 Nest 文档中的更多信息:https://docs.nestjs.com/techniques/streaming-files

关于javascript - 如何从 Controller 返回 PDF 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53504621/

相关文章:

javascript - Mongoose:带有通配符的 bool 值 'or' 查询

node.js - 如何通过部署在 Heroku 上的 Nodejs/Nestjs 服务器为我的 Angular 前端提供服务?

node.js - Nestjs:验证函数不适用于 jwt

javascript - 以像素为单位的字符大小

javascript - 没有 node.js 服务器的客户端 socket.io

javascript - 将元素添加到现有的 jQuery 集中

mysql - 远程连接到 Aurora Serverless

javascript - 如何在 Nestjs 中使用 .env 文件设置 Typeorm 的配置

javascript - 在终端中运行函数时无输出

javascript - 为什么我不能在 javascript 中将 1 加到一个大数上