如何使用 aws-sdk 获取 AWS S3 上文件的 URL?
Posted
技术标签:
【中文标题】如何使用 aws-sdk 获取 AWS S3 上文件的 URL?【英文标题】:How to get the URL of a file on AWS S3 using aws-sdk? 【发布时间】:2017-11-08 01:46:06 【问题描述】:我正在使用 AWS Lambda 函数创建一个文件并将其保存到我在 S3 上的存储桶中,它工作正常。执行putObject
方法后,我得到一个data
对象,但它只包含最近添加的对象的Etag
。
s3.putObject(params, function(err, data)
// data only contains Etag
);
我需要知道可以在浏览器中使用的确切 URL,以便客户端可以看到该文件。该文件夹已公开,如果我从 S3 控制台复制链接,我可以看到该文件。
我尝试使用getSignedUrl
,但我相信它返回的 URL 用于其他目的。
谢谢!
【问题讨论】:
预签名的 url 可以用作下载链接,但是,它会在 x 分钟后过期,用于非公共项目。如果您的项目是公开的,最简单的做法就是使用可预测的模式连接 URL。 如果我从 S3 控制台复制链接你看到那里的模式了吗?存储桶中每个对象的 URL 都遵循完全相同的模式。 【参考方案1】:SDK 通常不包含为公共可读对象创建 URL 的便捷方法。但是,当您调用 PutObject 时,您 提供了存储桶和对象的密钥,这就是您所需要的。您可以简单地将它们组合成对象的 URL,例如:
https://bucket.s3.amazonaws.com/key因此,例如,如果您的存储桶是 pablo
并且对象键是 dogs/toto.png
,请使用:
请注意,S3 密钥不以 /
前缀开头。密钥的形式为dogs/toto.png
,而不是/dogs/toto.png
。
对于特定于区域的存储桶,请参阅 Working with Amazon S3 Buckets 和 AWS S3 URL Styles。将上述网址中的s3
替换为s3.<region>.amazonaws.com
或s3-<region>.amazonaws.com
,例如:
如果您使用的是 IPv6,则一般 URL 格式为:
https://BUCKET.s3.dualstack.REGION.amazonaws.com对于某些存储桶,您可以使用较旧的路径样式 URL。路径样式的 URL 已被弃用,only work with buckets created on or before September 30, 2020。它们是这样使用的:
https://s3.amazonaws.com/bucket/key https://s3.amazonaws.com/pablo/dogs/toto.png https://s3.eu-west-1.amazonaws.com/seamus/dogs/setter.png https://s3.dualstack.REGION.amazonaws.com/BUCKET目前存在 TLS 和 SSL 证书问题,可能需要通过路径样式的 URL 访问某些名称中带有点 (.
) 的存储桶。 AWS 计划解决这个问题。请参阅AWS announcement。
注意:关于 object keys 某些字符需要特殊处理的一般指导。例如,空格编码为 +(加号),加号编码为 %2B。还有here。
【讨论】:
谢谢!我认为链接在某些命名场景中很容易发生意外更改。 关于命名注意事项的附加帖子:***.com/questions/7116450/… 这并不能解释如果您在上传的文件名中使用空格会发生什么。显然它们被替换为“+”,但也许还有更多这样的规则? @JorisMans 谢谢,添加了额外的参考资料。 就我而言,我也需要存储桶区域:http://s3.region.amazonaws.com/bucket/key
。对我来说,地区是eu-west-3
【参考方案2】:
如果您有 s3bucket 和文件名对象并想要提取 url,这里有一个选项:
function getUrlFromBucket(s3Bucket,fileName)
const config :params,region = s3Bucket;
const regionString = region.includes('us-east-1') ?'':('-' + region)
return `https://$params.Bucket.s3$regionString.amazonaws.com/$fileName`
;
【讨论】:
这不适用于非区域特定的存储桶。例如,us-east-1
中的存储桶没有该区域作为 url 的一部分。
@bPratik ,感谢您的评论,我编辑了代码以支持它...
也没有正确转义键
@jrochkind 是什么意思?【参考方案3】:
你可以用这个打另一个电话:
var params = Bucket: 'bucket', Key: 'key';
s3.getSignedUrl('putObject', params, function (err, url)
console.log('The URL is', url);
);
【讨论】:
仅在一定时间内有效 只有在 s3 文件不公开的情况下,获取签名的 url 才有意义以上是关于如何使用 aws-sdk 获取 AWS S3 上文件的 URL?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 aws-sdk 中的 s3 存储桶创建 Elastic Beanstalk 实例?
@aws-sdk/lib-storage 使用 JSONStream.stringify() 将 JSON 从 MongoDB 流式传输到 S3
使用 aws-sdk 将 gm 调整大小的图像流上传到 s3
为啥我在 s3 上的访问被拒绝(使用适用于 Node.js 的 aws-sdk)?