我正在 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 问题。对我所缺少的有什么想法吗?我很乐意根据需要提供更多详细信息。预先感谢!
如果在查询对象的元数据时,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>