如何从Amazon S3获取私有图片并在后端将二进制数据发送到前端渲染
私有S3图片获取并返回前端渲染方案
方案1:后端代理转发二进制流(适合需要做权限校验的场景)
步骤1:处理S3 getObject返回结果
你调用getObject拿到的返回结果里,Body属性是可读流类型,不需要额外提取其他属性,核心就是处理这个流返回给前端即可,Node.js环境下的完整示例代码如下:
// 先await拿到S3返回结果 const s3Response = await this.s3Client.getObject({ Bucket: SPACES_BUCKET_NAME, Key: key, });
步骤2:后端设置响应头并返回流
不需要把流转成Buffer再返回,直接用管道(pipe)的方式把S3的流传给前端响应即可,内存占用更低,以Express框架为例:
res.set({ // 直接复用S3返回的文件类型,保证前端能正确识别是图片 'Content-Type': s3Response.ContentType, 'Content-Length': s3Response.ContentLength, // 需要前端直接下载的话可以加下面的头,不需要渲染就注释掉 // 'Content-Disposition': `attachment; filename="${key}"` }) // 直接把S3的可读流pipe到响应对象 s3Response.Body.pipe(res)
步骤3:前端渲染方式
- 直接用img标签请求后端接口即可:
<img src="/你的后端接口地址/图片key" alt="渲染的图片">
- 如果是用fetch异步请求,需要转成blob生成临时URL:
const res = await fetch('/你的后端接口地址/图片key') const imgBlob = await res.blob() const imgUrl = URL.createObjectURL(imgBlob) document.querySelector('img').src = imgUrl // 页面销毁时记得调用释放内存 // URL.revokeObjectURL(imgUrl)
方案2:生成S3预签名URL(更推荐,节省后端资源)
如果不需要做复杂的权限校验,直接生成带有效期的预签名URL返回给前端是更优方案,前端可以直接用这个URL访问S3的私有资源,不需要走后端转发,性能更高:
// AWS SDK v3 示例 import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; import { GetObjectCommand } from "@aws-sdk/client-s3"; const getObjectCmd = new GetObjectCommand({ Bucket: SPACES_BUCKET_NAME, Key: key, }) // 生成有效期1小时的预签名URL,expiresIn单位为秒 const signedImgUrl = await getSignedUrl(this.s3Client, getObjectCmd, { expiresIn: 3600 })
前端直接把signedImgUrl赋值给img的src属性即可正常渲染。
注意事项
- 用预签名URL的话需要提前在S3控制台配置对应Bucket的CORS规则,允许你的前端域名跨域访问
- 预签名URL的有效期不要设置过长,避免链接泄露后被滥用
- 高敏感图片建议用方案1,后端可以做完整的权限校验,只有符合条件的请求才能拿到图片数据
内容的提问来源于stack exchange,提问作者Dogwrench
相关产品推荐
相关产品推荐

