NestJS从GridFS返回文件

7

我正在尝试使用Nest控制器从GridFS返回文件。据我所知,Nest没有遵守我设置为application/zip的自定义content-type头部,因为我在返回时收到了文本内容类型(请参见屏幕截图)。

响应数据图像,错误的内容类型标头

我的Nest控制器如下所示:

  @Get(':owner/:name/v/:version/download')
  @Header('Content-Type', 'application/zip')
  async downloadByVersion(@Param('owner') owner: string, @Param('name') name: string, @Param('version') version: string, @Res() res): Promise<any> {
    let bundleData = await this.service.getSwimbundleByVersion(owner, name, version);
    let downloadFile = await this.service.downloadSwimbundle(bundleData['meta']['fileData']['_id']);   
    return res.pipe(downloadFile);
  }

这是服务调用。
downloadSwimbundle(fileId: string): Promise<GridFSBucketReadStream> {
      return this.repository.getFile(fileId)
    }

这本质上是对这个的直接传递。

  async getFile(fileId: string): Promise<GridFSBucketReadStream> {
    const db = await this.dbSource.db;
    const bucket = new GridFSBucket(db, { bucketName: this.collectionName });
    const downloadStream = bucket.openDownloadStream(new ObjectID(fileId));

    return new Promise<GridFSBucketReadStream>(resolve => {
        resolve(downloadStream)
      });
  }

我的最终目标是调用下载端点,并使浏览器注册它为zip文件并下载它,而不是在浏览器中看到二进制文件。如果您能指导我如何实现这一目标,我将非常感激。谢谢阅读。
1个回答

10

你还需要设置带有文件名的Content-Disposition头。如果文件名始终相同,可以使用@Header()装饰器,或者如果需要基于控制器中某个参数发送不同的文件名,则可以直接在响应对象上使用setHeader

以下两个示例控制器方法都可以从本地文件系统向浏览器发送可下载文件。

@Get('/test')
@Header('Content-Type', 'application/pdf')
@Header('Content-Disposition', 'attachment; filename=something.pdf')
getTest(@Res() response: Response) {
   const data = createReadStream(path.join(__dirname, 'test.pdf'));
   data.pipe(response);
}

@Get('/test')
@Header('Content-Type', 'application/pdf')
getTest(@Res() response: Response) {
   const data = createReadStream(path.join(__dirname, 'test.pdf'));

   response.setHeader(
     'Content-Disposition',
     'attachment; filename=another.pdf',
   );

   data.pipe(response);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接