如何在NestJS+Angular项目中展示从AWS S3获取的图片
解决方法
后端改造(优先推荐)
你现在的后端接口直接返回S3的getObject结果,会被NestJS默认序列化为JSON格式,前端拿到的是格式化后的Buffer对象,无法直接作为图片使用,优先修改后端接口:
方案1:直接返回图片二进制流
这种方案前端不需要做任何转码处理,直接把接口地址作为img标签的src属性即可,性能最优。
修改S3Controller的对应方法:
import { Res } from '@nestjs/common'; import { Response } from 'express'; // 类中其他代码保持不变 async findImageByBucketNameAndKey( @Param() params: { bucket: string; key: string }, @Res() res: Response ): Promise<void> { const bucketName = params.bucket; const key = params.key; Logger.log( 'findImageByBucketNameAndKey(@Param() ' + bucketName + ', ' + key + ' )', S3Controller.name, ); const s3Data = await this.s3Client.getImage(bucketName, key); // 设置正确的响应头 res.setHeader('Content-Type', s3Data.ContentType); res.setHeader('Content-Length', s3Data.ContentLength); // 直接返回二进制流 res.send(s3Data.Body); }
前端直接使用:
<img src="你的服务地址/s3/find/my-image-bucket/12345.jpg" alt="图片">
方案2:后端转Base64返回
如果业务需要返回JSON格式数据,可以在后端直接把图片内容转成带MIME前缀的Base64字符串:
// 类中其他代码保持不变 async findImageByBucketNameAndKey( @Param() params: { bucket: string; key: string }, ): Promise<{base64: string} | null> { const bucketName = params.bucket; const key = params.key; Logger.log( 'findImageByBucketNameAndKey(@Param() ' + bucketName + ', ' + key + ' )', S3Controller.name, ); const s3Data = await this.s3Client.getImage(bucketName, key); const base64Str = s3Data.Body.toString('base64'); return { base64: `data:${s3Data.ContentType};base64,${base64Str}` }; }
前端拿到数据后直接赋值给img的src属性即可。
前端改造方案(不修改后端的情况)
如果你暂时不想修改后端代码,可以按以下步骤修改前端代码,完全避开Buffer不兼容的问题:
- 修改请求服务,指定响应类型为blob:
findImageByBucketNameAndKey(bucketName: string, key: string): Observable<Blob | null> { return this.http.get(environment.baseUrl + `s3/find/${bucketName}/${key}`, { responseType: 'blob' }); }
- 组件内用FileReader将blob转为可直接展示的DataURL:
vbrImage: string = ''; getImage(): void { const key = '12345.jpg'; this.requestClientService.findImageByBucketNameAndKey('my-image-bucket', key) .subscribe((blob) => { if (blob) { const reader = new FileReader(); reader.onload = () => { this.vbrImage = reader.result as string; }; reader.readAsDataURL(blob); } }); }
- 模板中直接绑定src:
<img [src]="vbrImage" alt="图片">
Buffer报错的根本原因是Node.js的Buffer API浏览器不原生支持,不需要额外安装buffer依赖,用上述浏览器原生的Blob+FileReader方案即可解决问题。
内容的提问来源于stack exchange,提问作者iranichai
相关产品推荐
相关产品推荐

