我在S3存储桶中有一堆文件。我需要遍历它们并添加一些元数据,为此我正在使用node client。 S3 API并没有像您想的那样简单。来自docs:
请注意,如果您选择更新任何对象的 复制期间用户可配置的元数据(系统或用户定义的), 那么您必须明确指定所有用户可配置的元数据 出现在请求中的源对象上,即使您只是 仅更改元数据值之一。
很好,但是仅当您具有S3对象可以拥有的元数据的完整列表时,此方法才有效。我找到了this list,但还不完整。例如,它不包含ContentType
。如果我用尽可能多的东西加载对象,我会得到:
aws s3api head-object --bucket my-bucket --key some-file
{
"AcceptRanges": "bytes",
"ContentType": "video/mp4",
"LastModified": "Sat, 18 May 2019 18:18:50 GMT",
"ContentLength": 50957711,
"VersionId": "null",
"ETag": "\"2d8a6acea8c37217a034d841084c6727-4\"",
"StorageClass": "ONEZONE_IA",
"ServerSideEncryption": "aws:kms",
"CacheControl": "cc",
"SSEKMSKeyId": "arn:aws:kms:us-east-1:999999999999:key/99999999-9999-9999-9999-999999999999",
"Metadata": {
"val1": "test1",
"val2": "test2"
}
}
是整个列表吗?我不知道,也找不到任何文档。如果aws决定以后再添加更多系统元数据,还会发生什么?
我还尝试过像这样复制现有的头部:
const p1 = { Bucket: bucket, Key: obj.Key, CopySource: `${bucket}/${obj.Key}`, MetadataDirective: 'REPLACE' };
const p2 = Object.assign(p1, head, { Metadata: { prop1: 'val1' } });
await s3.copyObject(p2).promise();
这会导致如下错误:
- UnexpectedParameter:在参数中找到了意外的键'ContentLength'
因为某些系统元数据是只读的。我可以简单地做到这一点
delete p2.ContentLength
但这有一个类似的问题,因为我不知道它们将来还会引入哪些其他只读元数据。至少我不必知道所有现有的元数据项。
或者如果有替代方法可以这样做。希望有人提出了一种更合理的方法来解决这个问题。