【发布时间】:2019-02-13 09:28:31
【问题描述】:
我有类似于以下的代码,使用 Express 将 S3 对象作为响应通过管道传回客户端,效果很好。
const s3 = new AWS.S3();
const params = {
Bucket: 'myBucket',
Key: 'myImageFile.jpg'
};
s3.getObject(params).createReadStream().pipe(res);
问题是,我希望能够访问从 S3 返回的响应中的一些属性,例如 LastModified、ContentLength、ETag 等。我想使用这些属性作为响应头发送给客户端,以及记录信息。
由于它正在创建一个流,我不知道如何获取这些属性。
我曾考虑单独调用s3.headObject 来获取我需要的数据,但这似乎真的很浪费,并且最终会大规模增加大量成本。
我也考虑过放弃整个流的想法,只让它返回一个缓冲区,但同样,当我不需要它时使用额外的内存似乎真的很浪费,并且可能会在规模上增加更多成本,因为处理请求所需的额外服务器和处理每个请求所需的额外内存。
如何使用s3.getObject 以及s3.getObject 通常会返回给您的所有元数据和其他属性取回流?
像下面这样的东西会很棒:
const s3 = new AWS.S3();
const params = {
Bucket: 'myBucket',
Key: 'myImageFile.jpg',
ReturnType: 'stream'
};
const s3Response = await s3.getObject(params).promise();
s3Response.Body.pipe(res); // where `s3Response.Body` is a stream
res.set("ETag", s3Response.ETag);
res.set("Content-Type", s3Response.ContentType);
console.log("Metadata: ", s3Response.Metadata);
但根据 S3 文档,这看起来不太可能。有没有其他方法可以实现这样的目标?
【问题讨论】:
-
您是否尝试过捕获原始
AWS.Request?var req = s3.getObject(params);然后req.createReadStream().pipe(res); ...你有req,它应该提供一些有用的属性或者你可以监听的事件。我没试过,但里面藏着很多看起来很有用的东西。 -
@Michael-sqlbot 是的,这真的行不通。因为我需要的数据仅在
end事件中可用。到那时标头已经发送,所以我无法调整标头。 -
哦,我想知道
res是在哪里定义的。我明白你在做什么了,现在。 -
@Michael-sqlbot 是的,我使用 Express 作为 Web 服务器,只是将来自 S3 的数据作为对客户端的响应进行管道传输。
-
有
httpHeaders事件,您可以在它们完成到达时获取标头,httpData看起来您应该看到响应正文数据以块的形式到达,您可以将其流式传输到管自己。
标签: javascript node.js amazon-web-services amazon-s3