我正在尝试使用 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/