Nest.js 和 Archiver - 将 zip 文件流传输到 http 响应中
Nest.js and Archiver - pipe stream zip file into http response
在我的 node.js 应用程序中,我从 AWS S3 下载多个用户文件,将它们压缩为单个 zip(使用 Archiver
npm 库)文件并发送回客户端。我一直在流上操作,但我无法将文件发送到客户端(因此客户端会在成功的 http 请求后开始下载)。
const filesStreams = await this.awsService.downloadFiles(
document?.documentFiles,
);
const zipStream = await this.compressService.compressFiles(filesStreams);
// ts-ignore
response.setHeader('Content-Type', 'application/octet-stream');
response.setHeader(
'Content-Disposition',
'attachment; filename="files.zip"',
);
zipStream.pipe(response);
其中 response 是明确的响应对象。 zipStream 是使用 Archiver 创建的:
public async compressFiles(files: DownloadedFileType[]): Promise<Archiver> {
const zip = archiver('zip');
for (const { stream, name } of files) {
zip.append((stream as unknown) as Readable, {
name,
});
}
return zip;
而且我知道它是正确的 - 因为当我将它通过管道传输到 WriteStream 到我的文件系统中的某个文件时它工作正常(我能够解压缩写入的文件并且它具有正确的内容)。可能我可以暂时在文件系统中写入文件,使用 response.download 将其发送回客户端,然后删除保存文件,但它看起来是非常低效的解决方案。任何帮助将不胜感激。
所以我找到了问题的根源 - 我将 post 放在这里只是为了记录,以防有人遇到同样的问题。问题的根源完全不同——我试图通过 AJAX 请求启动下载,这当然行不通。我更改了我的前端代码,而是 AJAX 我使用了 HTML 锚元素,其 src 属性设置在完全相同的端点上并且它工作得很好。
我有一个不同的问题,但它来自 lint。我需要从目录中读取所有文件,然后将它们以一个 zip 的形式发送给客户端。也许有人觉得有用。
有 2 个问题:
- 我将
cwd
与 root
不匹配;见 glob doc
- 因为我使用
PassThrough
作为 Archiever
和输出之间的代理对象,lint 显示 stream.pipe(response)
并输入问题...这是个错误 - 它工作正常。
在我的 node.js 应用程序中,我从 AWS S3 下载多个用户文件,将它们压缩为单个 zip(使用 Archiver
npm 库)文件并发送回客户端。我一直在流上操作,但我无法将文件发送到客户端(因此客户端会在成功的 http 请求后开始下载)。
const filesStreams = await this.awsService.downloadFiles(
document?.documentFiles,
);
const zipStream = await this.compressService.compressFiles(filesStreams);
// ts-ignore
response.setHeader('Content-Type', 'application/octet-stream');
response.setHeader(
'Content-Disposition',
'attachment; filename="files.zip"',
);
zipStream.pipe(response);
其中 response 是明确的响应对象。 zipStream 是使用 Archiver 创建的:
public async compressFiles(files: DownloadedFileType[]): Promise<Archiver> {
const zip = archiver('zip');
for (const { stream, name } of files) {
zip.append((stream as unknown) as Readable, {
name,
});
}
return zip;
而且我知道它是正确的 - 因为当我将它通过管道传输到 WriteStream 到我的文件系统中的某个文件时它工作正常(我能够解压缩写入的文件并且它具有正确的内容)。可能我可以暂时在文件系统中写入文件,使用 response.download 将其发送回客户端,然后删除保存文件,但它看起来是非常低效的解决方案。任何帮助将不胜感激。
所以我找到了问题的根源 - 我将 post 放在这里只是为了记录,以防有人遇到同样的问题。问题的根源完全不同——我试图通过 AJAX 请求启动下载,这当然行不通。我更改了我的前端代码,而是 AJAX 我使用了 HTML 锚元素,其 src 属性设置在完全相同的端点上并且它工作得很好。
我有一个不同的问题,但它来自 lint。我需要从目录中读取所有文件,然后将它们以一个 zip 的形式发送给客户端。也许有人觉得有用。
有 2 个问题:
- 我将
cwd
与root
不匹配;见 glob doc - 因为我使用
PassThrough
作为Archiever
和输出之间的代理对象,lint 显示stream.pipe(response)
并输入问题...这是个错误 - 它工作正常。