AWS S3 对象元数据尽管已设置但未返回

问题描述 投票:0回答:1

我正在 Node 中使用 AWS S3 创建一个 Web 服务,用户在其中上传应该具有作者元数据标签的文件。当用户上传时,会创建以下类型的预签名 URL,以便在客户端安全地上传文件,并编辑敏感值(由于我的托管服务的限制,无法选择完整的服务器端上传) :

https://my-website.s3.tebi.io/category/subcategory/file_name.wav?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=<redacted>&X-Amz-Date=<redacted>&X-Amz-Expires=900&X-Amz-Signature=<redacted>&X-Amz-SignedHeaders=host&x-amz-meta-author=John%20Doe&x-id=PutObject

然后通过发送带有上述内容的

Fetch
请求来完成文件上传
signedURL
:

fetch(signedURL, {
    method: 'PUT',
    headers: {
        "Content-Length": new Blob([file]).size
    },
    body: new Blob([file], { type: mimeType })
})
.then(response => {
    if(response.ok) fileUploaded = true;
})
.catch(error => console.error(error));

我可以通过

ListObjectsV2Command
成功查看上传的文件,但是当我尝试通过
HeadObjectCommand
查看存储桶中对象的元数据时,找不到
x-amz-meta-author
(而其他元数据完全按照预期显示,包括文件大小):

{
  data: {
    '$metadata': {
      httpStatusCode: 200,
      requestId: '<redacted>',
      extendedRequestId: 'node-usw-2',
      cfId: undefined,
      attempts: 1,
      totalRetryDelay: 0
    },
    AcceptRanges: 'bytes',
    LastModified: <redacted>,
    ContentLength: 66528,
    ETag: '"<redacted>"',
    CacheControl: 'no-cache',
    ContentType: 'audio/flac',
    Metadata: {}
  }
}

我已仔细检查以确保

x-amz-meta-author
位于
ExposedHeader
列表中,以避免 CORS 问题。对我所缺少的有什么想法吗?我很乐意根据需要提供更多详细信息。预先感谢!

node.js amazon-web-services amazon-s3
1个回答
0
投票

如果在查询对象的元数据时,AWS S3 元数据未按预期显示,请首先检查您生成的签名 URL 是否确实包含正确编码的

x-amz-meta-author
参数。您提供的 URL 似乎正确,但您可能需要确认元数据是否正确包含在每个请求中。

  Client-side (Browser)                   AWS S3 Bucket
  ┌───────────────────────────┐           ┌─────────────────────────────┐
  │ Generate Pre-signed URL   │           │                             │
  │ x-amz-meta-author=JohnDoe ├──────────>│   Object uploaded with      │
  │ for PUT operation         │           │   metadata                  │
  └───────────────────────────┘           │                             │
                                          └─────────────────────────────┘

您的 fetch 调用可能会在上传过程中删除元数据。为了确保在

PUT
请求期间尊重元数据标头,请在提取请求的 标头中明确设置它们:

fetch(signedURL, {
    method: 'PUT',
    headers: {
        "Content-Type": mimeType,
        "x-amz-meta-author": "John Doe",
        "Content-Length": new Blob([file]).size
    },
    body: new Blob([file], { type: mimeType })
})
.then(response => {
    if(response.ok) fileUploaded = true;
})
.catch(error => console.error(error));

上传后,使用 AWS 开发工具包获取并记录元数据以确保其设置正确。这可以在服务器代码中的单独管理路由或函数中完成:

const { S3Client, HeadObjectCommand } = require("@aws-sdk/client-s3");
const client = new S3Client({ region: "your-region" });

const headObjectParams = {
    Bucket: "your-bucket-name",
    Key: "category/subcategory/file_name.wav"
};

const command = new HeadObjectCommand(headObjectParams);

client.send(command).then(data => {
    console.log(data.Metadata); // Check metadata here
}).catch(console.error);

尽管您提到检查

ExposedHeaders
,但最好还是验证 S3 存储桶上的 CORS 设置,以确保暴露
x-amz-meta-*
标头:

<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    <ExposeHeader>x-amz-meta-author</ExposeHeader>
</CORSRule>
© www.soinside.com 2019 - 2024. All rights reserved.