首页 > 解决方案 > AWS S3 headObject 未返回 JS SDK 中的所有元数据值

问题描述

我在 AWS S3 存储桶中有一个对象,上面设置了一些元数据键。我通过headObject()在 AWS v2 JavaScript SDK 中使用来获取键和值。

const headParams = {
    Bucket: "THE_BUCKET", 
    Key: "THE_KEY"
};

S3.headObject(headParams, (err, data) => {
    if(err) {
        console.log(err);
    } else {
        console.log(data);
    }
});

如果我然后使用以下键“修改”其中之一copyObject()

objectMetadata["SOME_EXISTING_METADATA_KEY"] = "Some New Value";

const params = {    
    Bucket: "THE_BUCKET", 
    Key: "THE_KEY",
    CopySource: "THE_BUCKET/THE_KEY",
    MetadataDirective: "REPLACE",
    ACL: "public-read",
    'Metadata': objectMetadata
};

S3.copyObject(params, (err, data) => {
    if(err) {
        console.log(err);
    } else {
        console.log(data);
    }
});

然后headObject()再次调用,我得到了更新的值,正如预期的那样。

如果我使用copyObject()上面相同的代码,但尝试添加对象上尚不存在的新元数据键:

...
objectMetadata["SOME_NEW_METADATA_KEY"] = "Some New Value";
...

我在 S3 控制台中看到了新值,但是当我headObject()再次调用时,新的元数据键没有出现。

但是,LastModified标头中的时间戳显示当我添加新密钥时对象已被修改。而且,如果我使用 AWS CLI 检索同一对象的元数据,新键确实会出现:

aws s3api head-object --bucket THE_BUCKET --key THE_KEY

{
    "AcceptRanges": "bytes",
    "LastModified": "2021-05-03T19:06:14+00:00",
    "ContentLength": 18340648,
    "ETag": "\"a8...\"",
    "ContentType": "application/octet-stream; charset=UTF-8",
    "Metadata": {
        ...
        "SOME_NEW_METADATA_KEY": "Some New Value",
        ...
    }
}

有人见过这种行为吗?我无法弄清楚为什么密钥会出现在控制台和 CLI 的结果中,而不是 JavaScript SDK。特别是因为 SDK 显示更新现有密钥的结果很好。

标签: javascriptamazon-web-servicesamazon-s3aws-sdk-js

解决方案


我的一位同事能够追踪到这一点。万一其他人遇到此问题,结果证明是 CORS 配置问题*。

每个元数据键都需要显式添加为CORS 配置中的 ExposeHeader 条目

这是 CORS 配置中的相关部分,您可以在 S3 的“权限”选项卡下的“跨域资源共享”部分中对其进行编辑:

    "ExposeHeaders": [
        ...
        "SOME_EXISTING_METADATA_KEY",
        "SOME_NEW_METADATA_KEY"
    ]

* 应该知道。正如我祖父喜欢说的,“当网络上的某些东西不能正常工作时,它可能是 CORS 问题。”


推荐阅读