NestJS return 来自 GridFS 的文件
NestJS return a fie from GridFS
我正在尝试使用我的 Nest 控制器 return 来自 GridFS 的文件。据我所知,nest 不尊重我设置为 application/zip
的自定义 content-type
header,因为我在 return 上收到文本内容类型(见屏幕截图) .
response data image, wrong content-type header
我的 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)
}
本质上是 pass-through 到此。
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)
});
}
我的最终目标是调用 download
端点并让浏览器注册它是一个 zip 文件并下载它,而不是在浏览器中看到二进制文件。任何关于到达那里需要做什么的指导将不胜感激。感谢阅读
您还需要设置 Content-Disposition
header 文件名。如果文件名始终相同,则可以使用 @Header()
装饰器;如果需要根据某些参数返回不同的文件名,则可以直接在响应 object 上使用 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);
}
我正在尝试使用我的 Nest 控制器 return 来自 GridFS 的文件。据我所知,nest 不尊重我设置为 application/zip
的自定义 content-type
header,因为我在 return 上收到文本内容类型(见屏幕截图) .
response data image, wrong content-type header
我的 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)
}
本质上是 pass-through 到此。
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)
});
}
我的最终目标是调用 download
端点并让浏览器注册它是一个 zip 文件并下载它,而不是在浏览器中看到二进制文件。任何关于到达那里需要做什么的指导将不胜感激。感谢阅读
您还需要设置 Content-Disposition
header 文件名。如果文件名始终相同,则可以使用 @Header()
装饰器;如果需要根据某些参数返回不同的文件名,则可以直接在响应 object 上使用 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);
}