有没有办法使用 AWS CLI 获取 S3 对象的位置 (public url)?
Is there a way to get location (public url) of S3 object using AWS CLI?
<前提>
我总体上是新的云计算,特别是 AWS
和 REST API,我正在尝试拼凑一个 "big-picture" 的理解。
我正在使用 LocalStack
- 据我所知,它通过对 AWS
API 的(子集)做出相同的响应来模拟真实的 AWS
if您指定 LocalStack
侦听的端点 address/port。
最后,我一直在学习本教程:https://dev.to/goodidea/how-to-fake-aws-locally-with-localstack-27me
前提>
使用提到的教程并根据其指导,我使用 AWS
CLI 成功创建了一个 S3
存储桶。
不过,为了演示将本地文件上传到 S3
存储桶,本教程切换到 node.js
,我认为它演示了 AWS
node.js
SDK:
# aws.js
# This code segment comes from https://dev.to/goodidea/how-to-fake-aws-locally-with-localstack-27me
#
const AWS = require('aws-sdk')
require('dotenv').config()
const credentials = {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_KEY,
}
const useLocal = process.env.NODE_ENV !== 'production'
const bucketName = process.env.AWS_BUCKET_NAME
const s3client = new AWS.S3({
credentials,
/**
* When working locally, we'll use the Localstack endpoints. This is the one for S3.
* A full list of endpoints for each service can be found in the Localstack docs.
*/
endpoint: useLocal ? 'http://localhost:4572' : undefined,
/**
* Including this option gets localstack to more closely match the defaults for
* live S3. If you omit this, you will need to add the bucketName to the `Key`
* property in the upload function below.
*
* see: https://github.com/localstack/localstack/issues/1180
*/
s3ForcePathStyle: true,
})
const uploadFile = async (data, fileName) =>
new Promise((resolve) => {
s3client.upload(
{
Bucket: bucketName,
Key: fileName,
Body: data,
},
(err, response) => {
if (err) throw err
resolve(response)
},
)
})
module.exports = uploadFile
.
# test-upload.js
# This code segment comes from https://dev.to/goodidea/how-to-fake-aws-locally-with-localstack-27me
#
const fs = require('fs')
const path = require('path')
const uploadFile = require('./aws')
const testUpload = () => {
const filePath = path.resolve(__dirname, 'test-image.jpg')
const fileStream = fs.createReadStream(filePath)
const now = new Date()
const fileName = `test-image-${now.toISOString()}.jpg`
uploadFile(fileStream, fileName).then((response) => {
console.log(":)")
console.log(response)
}).catch((err) => {
console.log(":|")
console.log(err)
})
}
testUpload()
调用:
$ node test-upload.js
:)
{ ETag: '"c6b9e5b1863cd01d3962c9385a9281d"',
Location: 'http://demo-bucket.localhost:4572/demo-bucket/test-image-2019-03-11T21%3A22%3A43.511Z.jpg',
key: 'demo-bucket/test-image-2019-03-11T21:22:43.511Z.jpg',
Key: 'demo-bucket/test-image-2019-03-11T21:22:43.511Z.jpg',
Bucket: 'demo-bucket' }
我之前没有使用过node.js,但是我对上面代码的理解是,它使用了AWS.S3.upload()
AWS
node.js
SDK方法来复制一个本地文件到 S3
存储桶,并打印 HTTP
响应(正确吗?)。
问题:我观察到 HTTP
响应包含一个 "Location" 键,其值看起来像 URL 我可以 copy/paste 进入浏览器以直接从 S3
存储桶中查看图像;有没有办法使用 AWS
CLI 获取此位置?
我假设 AWS
CLI 命令是 AWS
SDK 的类似物是否正确?
我尝试使用 aws s3 cp
CLI 命令将文件上传到我的 S3 存储桶,我认为这类似于上面的 AWS.S3.upload()
方法,但它没有生成任何输出,并且我不确定我应该做什么 - 或者应该做什么 - 以 HTTP 对 AWS.S3.upload()
AWS 节点 SDK 方法的响应方式获取位置。
$ aws --endpoint-url=http://localhost:4572 s3 cp ./myFile.json s3://myBucket/myFile.json
upload: ./myFile.json to s3://myBucket/myFile.json
更新:继续研究让我现在想知道上传到 S3
存储桶的文件是否 隐式 任何方式 - 无论是通过 CLI 命令 aws s3 cp
还是 node.js SDK 方法 AWS.S3.upload()
等 - 都可以在 http://<bucket_name>.<endpoint_without_http_prefix>/<bucket_name>/<key>
访问?例如。 http://myBucket.localhost:4572/myBucket/myFile.json
?
如果这是 隐含的 ,我想你可能会争辩说没有必要像那个例子 node.js
HTTP 响应那样给定 "Location"。
感谢您的指导 - 我希望很明显我在所有相关技术上的教育程度很低。
更新 2:看起来正确的 url 是 <endpoint>/<bucket_name>/<key>
,例如http://localhost:4572/myBucket/myFile.json
.
AWS CLI 和不同的 SDK 提供相似的功能,但有些会添加额外的功能,有些会以不同的方式设置数据格式。可以安全地假设您可以执行 CLI 使用 SDK 执行的操作,反之亦然。有时你可能只需要为它工作一点。
正如您在更新中所说,并非每个上传到 S3 的文件都 public 可用。桶有策略,文件有权限。如果策略和权限允许,文件仅 public 可用。
如果文件是 public 那么您可以按照您的描述构造 URL。如果您有用于网站托管的存储桶设置,您还可以使用您设置的域。
但是如果文件不是 public 或者您只是想要一个临时文件 URL,您可以使用 aws presign s3://myBucket/myFile.json
。这会给你一个 URL ,任何人都可以使用它来下载具有执行命令的人的权限的文件。 URL 的有效期为一小时,除非您使用 --expires-in
选择不同的时间。 SDK 也有类似的功能,但您需要稍微努力才能使用它。
注意:从版本 0.11.0 开始,所有 API 都通过单个边缘服务公开,默认情况下可在 http://localhost:4566 上访问。
考虑到您已将一些文件添加到存储桶
aws --endpoint-url http://localhost:4566 s3api list-objects-v2 --bucket mybucket
{
"Contents": [
{
"Key": "blog-logo.png",
"LastModified": "2020-12-28T12:47:04.000Z",
"ETag": "\"136f0e6acf81d2d836043930827d1cc0\"",
"Size": 37774,
"StorageClass": "STANDARD"
}
]
}
您应该可以使用
访问您的文件
http://localhost:4566/mybucket/blog-logo.png
<前提>
我总体上是新的云计算,特别是 AWS
和 REST API,我正在尝试拼凑一个 "big-picture" 的理解。
我正在使用 LocalStack
- 据我所知,它通过对 AWS
API 的(子集)做出相同的响应来模拟真实的 AWS
if您指定 LocalStack
侦听的端点 address/port。
最后,我一直在学习本教程:https://dev.to/goodidea/how-to-fake-aws-locally-with-localstack-27me
前提>
使用提到的教程并根据其指导,我使用 AWS
CLI 成功创建了一个 S3
存储桶。
不过,为了演示将本地文件上传到 S3
存储桶,本教程切换到 node.js
,我认为它演示了 AWS
node.js
SDK:
# aws.js
# This code segment comes from https://dev.to/goodidea/how-to-fake-aws-locally-with-localstack-27me
#
const AWS = require('aws-sdk')
require('dotenv').config()
const credentials = {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_KEY,
}
const useLocal = process.env.NODE_ENV !== 'production'
const bucketName = process.env.AWS_BUCKET_NAME
const s3client = new AWS.S3({
credentials,
/**
* When working locally, we'll use the Localstack endpoints. This is the one for S3.
* A full list of endpoints for each service can be found in the Localstack docs.
*/
endpoint: useLocal ? 'http://localhost:4572' : undefined,
/**
* Including this option gets localstack to more closely match the defaults for
* live S3. If you omit this, you will need to add the bucketName to the `Key`
* property in the upload function below.
*
* see: https://github.com/localstack/localstack/issues/1180
*/
s3ForcePathStyle: true,
})
const uploadFile = async (data, fileName) =>
new Promise((resolve) => {
s3client.upload(
{
Bucket: bucketName,
Key: fileName,
Body: data,
},
(err, response) => {
if (err) throw err
resolve(response)
},
)
})
module.exports = uploadFile
.
# test-upload.js
# This code segment comes from https://dev.to/goodidea/how-to-fake-aws-locally-with-localstack-27me
#
const fs = require('fs')
const path = require('path')
const uploadFile = require('./aws')
const testUpload = () => {
const filePath = path.resolve(__dirname, 'test-image.jpg')
const fileStream = fs.createReadStream(filePath)
const now = new Date()
const fileName = `test-image-${now.toISOString()}.jpg`
uploadFile(fileStream, fileName).then((response) => {
console.log(":)")
console.log(response)
}).catch((err) => {
console.log(":|")
console.log(err)
})
}
testUpload()
调用:
$ node test-upload.js
:)
{ ETag: '"c6b9e5b1863cd01d3962c9385a9281d"',
Location: 'http://demo-bucket.localhost:4572/demo-bucket/test-image-2019-03-11T21%3A22%3A43.511Z.jpg',
key: 'demo-bucket/test-image-2019-03-11T21:22:43.511Z.jpg',
Key: 'demo-bucket/test-image-2019-03-11T21:22:43.511Z.jpg',
Bucket: 'demo-bucket' }
我之前没有使用过node.js,但是我对上面代码的理解是,它使用了AWS.S3.upload()
AWS
node.js
SDK方法来复制一个本地文件到 S3
存储桶,并打印 HTTP
响应(正确吗?)。
问题:我观察到 HTTP
响应包含一个 "Location" 键,其值看起来像 URL 我可以 copy/paste 进入浏览器以直接从 S3
存储桶中查看图像;有没有办法使用 AWS
CLI 获取此位置?
我假设 AWS
CLI 命令是 AWS
SDK 的类似物是否正确?
我尝试使用 aws s3 cp
CLI 命令将文件上传到我的 S3 存储桶,我认为这类似于上面的 AWS.S3.upload()
方法,但它没有生成任何输出,并且我不确定我应该做什么 - 或者应该做什么 - 以 HTTP 对 AWS.S3.upload()
AWS 节点 SDK 方法的响应方式获取位置。
$ aws --endpoint-url=http://localhost:4572 s3 cp ./myFile.json s3://myBucket/myFile.json
upload: ./myFile.json to s3://myBucket/myFile.json
更新:继续研究让我现在想知道上传到 S3
存储桶的文件是否 隐式 任何方式 - 无论是通过 CLI 命令 aws s3 cp
还是 node.js SDK 方法 AWS.S3.upload()
等 - 都可以在 http://<bucket_name>.<endpoint_without_http_prefix>/<bucket_name>/<key>
访问?例如。 http://myBucket.localhost:4572/myBucket/myFile.json
?
如果这是 隐含的 ,我想你可能会争辩说没有必要像那个例子 node.js
HTTP 响应那样给定 "Location"。
感谢您的指导 - 我希望很明显我在所有相关技术上的教育程度很低。
更新 2:看起来正确的 url 是 <endpoint>/<bucket_name>/<key>
,例如http://localhost:4572/myBucket/myFile.json
.
AWS CLI 和不同的 SDK 提供相似的功能,但有些会添加额外的功能,有些会以不同的方式设置数据格式。可以安全地假设您可以执行 CLI 使用 SDK 执行的操作,反之亦然。有时你可能只需要为它工作一点。
正如您在更新中所说,并非每个上传到 S3 的文件都 public 可用。桶有策略,文件有权限。如果策略和权限允许,文件仅 public 可用。
如果文件是 public 那么您可以按照您的描述构造 URL。如果您有用于网站托管的存储桶设置,您还可以使用您设置的域。
但是如果文件不是 public 或者您只是想要一个临时文件 URL,您可以使用 aws presign s3://myBucket/myFile.json
。这会给你一个 URL ,任何人都可以使用它来下载具有执行命令的人的权限的文件。 URL 的有效期为一小时,除非您使用 --expires-in
选择不同的时间。 SDK 也有类似的功能,但您需要稍微努力才能使用它。
注意:从版本 0.11.0 开始,所有 API 都通过单个边缘服务公开,默认情况下可在 http://localhost:4566 上访问。
考虑到您已将一些文件添加到存储桶
aws --endpoint-url http://localhost:4566 s3api list-objects-v2 --bucket mybucket
{
"Contents": [
{
"Key": "blog-logo.png",
"LastModified": "2020-12-28T12:47:04.000Z",
"ETag": "\"136f0e6acf81d2d836043930827d1cc0\"",
"Size": 37774,
"StorageClass": "STANDARD"
}
]
}
您应该可以使用
访问您的文件http://localhost:4566/mybucket/blog-logo.png