无法在Amazon S3上传发送/接收自定义元数据(使用ng-file-upload)

时间:2016-09-14 11:49:14

标签: amazon-s3 ng-file-upload

我正在使用ng-file-upload将JPG文件上传到我的S3 Bucket。

file.upload = Upload.upload({
    url: "https://<my-bucket-name>.s3.amazonaws.com/", 
    method: "POST",
    data: {
        key: "custom-filename.jpg", 
        AWSAccessKeyId: "<AWSAccessKeyId>",
        acl: "public-read", 
        policy: <policy>, 
        signature: <signature>, 
        "Content-Type": "image/jpeg", 
        filename: file.name, 
        file: file, 
        Metadata: {
            "x-amz-meta-hello": "Custom Metadata Value"
        }
    }
});

我也尝试了以下(在上面的代码中)

Metadata: {
    hello: "Custom Metadata Value"
}

&安培;简单地

"x-amz-meta-hello": "Custom Metadata Value"

我已将自定义元数据包含在我的策略文件中

["starts-with", "x-amz-meta-hello", ""]

此外,S3上的Bucket权限下的CORS配置是

<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <ExposeHeader>x-amz-meta-hello</ExposeHeader>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>

以上代码和设置正常运行,JPG文件已成功上传,但某些方式未设置自定义元数据值。

成功上传后,我调用Lambda函数来调整JPG的大小并将其存储在一个单独的存储桶中。即使这部分工作正常,但我无法在Lambda函数中读取自定义元数据(x-amz-meta-hello)值。我需要该值为上传的文件分配一个单独的文件夹。

阅读我的Lambda函数中的自定义元数据

var s3 = new AWS.S3();
s3.headObject({
    Bucket: <BucketName>,
    Key: <S3ObjectKey>
}, function(err, data) {
    if (err) {
        console.log(err);
    }
    else
    {   
        console.log(data);
    }     
});

不确定我在这里失踪了什么......请告知。

感谢。 (AngularJS版本1.5.0,ng-file-upload版本12.2.9,OSX 10.10.5上的Google Chrome版本53.0.2785.113)

1 个答案:

答案 0 :(得分:1)

删除Metadata: { ... }构造,因为您正在构建一个具有平面键空间的HTML表单。在其他地方,您可能会看到给予特殊处理的元数据,其中Metadata: { "hello": "world" }神奇地变为x-amz-meta-hello: world,但这不适用于此处。相反,元数据需要start with x-amz-meta-,因为我们是making a POST request,所以它在表单数据中提供,而不是作为标题提供。

因为文件数据需要是最后一个表单元素,所以将元数据键放在文件信息上方,例如:

...
"Content-Type": "image/jpeg", 
"x-amz-meta-hello": "Custom Metadata Value", 
filename: file.name, 
...

您的policy condition必须使用$引用元数据名称才能正常工作(["starts-with", "$x-amz-meta-hello", ""])。请注意,要接受该字段需要使用该策略,但此特定条件不会将该字段限制为包含特定值。

另请注意,为了允许上传,<ExposeHeader>x-amz-meta-hello</ExposeHeader>不是必需的。 <ExposeHeader>允许浏览器将该响应头返回给AJAX请求上的调用代码。未列出的标题(除“简单”标准标题之外,如Content-Type)在调用代码时是隐藏的。 CORS最初是违反直觉的,直到你明白它是基于Web浏览器本身被认为是善意但天真的想法。 CORS允许浏览器执行其他方式无法执行的操作,例如将特定标头返回给调用方。