使用 Node JS 创建 S3 签名 Url 时出现 "NoSuchKey" 错误
Getting "NoSuchKey" error when creating S3 signedUrl with NodeJS
我正在尝试使用 aws-sdk
.
通过 nodejs
访问 S3 存储桶
当我调用 s3.getSignedUrl
方法并使用它提供的 url 时,我在 url.
中收到“NoSuchKey”错误
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Key>{MY_BUCKET_NAME}/{REQUESTED_FILENAME}</Key>
我的理论是我传递的请求路径是错误的。比较我的要求:
{BUCKET_NAME}.s3.{BUCKET_REGION}.amazonaws.com/{BUCKET_NAME}/{KEY}
使用从 AWS 控制台创建的 url:
{BUCKET_NAME}.s3.{BUCKET_REGION}.amazonaws.com/{KEY}
为什么 aws-sdk
在末尾添加“{BUCKET_NAME}”?
NodeJS 代码:
// s3 instance setup
const s3 = new AWS.S3({
region: BUCKET_REGION,
endpoint: BUCKET_ENDPOINT, // {MY_BUCKET_NAME}.s3.{REGION}.amazonaws.com
s3ForcePathStyle: true,
signatureVersion: "v4",
});
const getSignedUrlFromS3 = async (filename) => {
const s3Params = {
Bucket: BUCKET_NAME,
Key: filename,
Expires: 60,
};
const signedUrl = await s3.getSignedUrl("getObject", s3Params);
return { name: filename, url: signedUrl };
};
SDK 在路径中添加存储桶名称,因为您明确要求它:
s3ForcePathStyle: true,
但是,根据您的评论,您已经在端点中使用了存储桶名称(“我的端点是 {MY_BUCKET_NAME}.s3.{REGION}.amazonaws.com
”),因此您的端点 不是 意味着使用路径样式...
路径样式意味着使用 s3.amazonaws.com/bucket/key
而不是 bucket.s3.amazonaws.com/key
。使用实际上已经包含存储桶名称的端点强制路径样式以 bucket.s3.amazonaws.com/bucket/key
结束,它被解释为键 bucket/key
而不是 key
.
修复应该是禁用 s3ForcePathStyle
而不是设置 s3BucketEndpoint: true
因为您为单个存储桶指定了端点。
但是,我认为没有必要首先指定端点 - 让 SDK 为您处理这些事情即可!我会同时删除 s3ForcePathStyle
和 endpoint
(然后也不需要 s3BucketEndpoint
)。
我正在尝试使用 aws-sdk
.
nodejs
访问 S3 存储桶
当我调用 s3.getSignedUrl
方法并使用它提供的 url 时,我在 url.
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Key>{MY_BUCKET_NAME}/{REQUESTED_FILENAME}</Key>
我的理论是我传递的请求路径是错误的。比较我的要求:
{BUCKET_NAME}.s3.{BUCKET_REGION}.amazonaws.com/{BUCKET_NAME}/{KEY}
使用从 AWS 控制台创建的 url:
{BUCKET_NAME}.s3.{BUCKET_REGION}.amazonaws.com/{KEY}
为什么 aws-sdk
在末尾添加“{BUCKET_NAME}”?
NodeJS 代码:
// s3 instance setup
const s3 = new AWS.S3({
region: BUCKET_REGION,
endpoint: BUCKET_ENDPOINT, // {MY_BUCKET_NAME}.s3.{REGION}.amazonaws.com
s3ForcePathStyle: true,
signatureVersion: "v4",
});
const getSignedUrlFromS3 = async (filename) => {
const s3Params = {
Bucket: BUCKET_NAME,
Key: filename,
Expires: 60,
};
const signedUrl = await s3.getSignedUrl("getObject", s3Params);
return { name: filename, url: signedUrl };
};
SDK 在路径中添加存储桶名称,因为您明确要求它:
s3ForcePathStyle: true,
但是,根据您的评论,您已经在端点中使用了存储桶名称(“我的端点是 {MY_BUCKET_NAME}.s3.{REGION}.amazonaws.com
”),因此您的端点 不是 意味着使用路径样式...
路径样式意味着使用 s3.amazonaws.com/bucket/key
而不是 bucket.s3.amazonaws.com/key
。使用实际上已经包含存储桶名称的端点强制路径样式以 bucket.s3.amazonaws.com/bucket/key
结束,它被解释为键 bucket/key
而不是 key
.
修复应该是禁用 s3ForcePathStyle
而不是设置 s3BucketEndpoint: true
因为您为单个存储桶指定了端点。
但是,我认为没有必要首先指定端点 - 让 SDK 为您处理这些事情即可!我会同时删除 s3ForcePathStyle
和 endpoint
(然后也不需要 s3BucketEndpoint
)。