Невозможно отправить/получить пользовательские метаданные при загрузке Amazon S3 (используя ng-file-upload)

Я использую ng-file-upload для загрузки файла JPG в свой ведро S3.

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", ""]

Кроме того, конфигурация CORS в разделе «Разрешения сегмента» на S3

<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 и сохранить его в отдельном сегменте. Даже эта часть работает, но я не могу прочитать значение пользовательских метаданных (x-amz-meta-hello) в моей лямбда-функции. Мне нужно это значение, чтобы назначить отдельную папку для загруженного файла.

Чтобы прочитать пользовательские метаданные в моей лямбда-функции

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, Google Chrome версии 53.0.2785.113 на OSX 10.10.5)


person SH59    schedule 14.09.2016    source источник
comment
Строго по наитию: уберите конструкцию Metadata: { и } и поместите ключ метаданных над информацией о файле: ... "Content-Type": "image/jpeg", "x-amz-meta-hello": "Custom Metadata Value", filename: file.name, ...   -  person Michael - sqlbot    schedule 15.09.2016
comment
Спасибо... Сработало отлично...   -  person SH59    schedule 15.09.2016


Ответы (1)


Удалите конструкцию Metadata: { ... }, потому что вы создаете HTML-форму с плоским пространством ключей. В других местах вы можете увидеть метаданные с особой обработкой, где что-то вроде Metadata: { "hello": "world" } волшебным образом становится x-amz-meta-hello: world, но здесь это неприменимо. Вместо этого метаданные должны начинаться с x-amz-meta-. , и поскольку мы отправляем POST запрос, предоставляется в данных формы, а не в заголовке.

Поскольку данные файла должны быть последним элементом формы, поместите ключ метаданных над информацией о файле, например:

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

Ваше условие политики должно ссылаться на имя метаданных с $ для работы (["starts-with", "$x-amz-meta-hello", ""]). Обратите внимание, что для того, чтобы поле было принято, требуется наличие политики, но это конкретное условие не ограничивает наличие в поле определенного значения.

Также обратите внимание, что <ExposeHeader>x-amz-meta-hello</ExposeHeader> не требуется для разрешения загрузки. <ExposeHeader> позволяет браузеру возвращать этот заголовок ответа вызывающему коду по запросу AJAX. Неуказанные заголовки (кроме «простых» стандартных, таких как Content-Type) иначе скрыты от вызывающего кода. CORS изначально нелогичен, пока вы не поймете, что он основан на идее, что сам веб-браузер считается благонамеренным, но наивным. CORS дает браузеру разрешение делать то, что в противном случае он бы не сделал, например, возвращать определенные заголовки обратно вызывающей стороне.

person Michael - sqlbot    schedule 15.09.2016
comment
Это кажется неправильным, если вы попытаетесь добавить метаданные в объект данных формы, вы получите ответ об ошибке, жалующийся на дополнительное поле. Кроме того, насколько я понимаю из документации S3, метаданные должны предоставляться через заголовки, начинающиеся с x-amz-meta-. (Это позволяет загружать файл, но метаданные не устанавливаются.) - person Rahat Ahmed; 30.01.2017
comment
Неважно, я ошибся. Вместо этого для запроса POST заголовки должны отправляться в виде данных формы. docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPOST. html Приношу извинения за преждевременное понижение. - person Rahat Ahmed; 30.01.2017
comment
Также условие политики должно использовать $x-amz-meta-hello для работы. - person Rahat Ahmed; 30.01.2017
comment
@RahatAhmed спасибо, ваше редактирование было одобрено, так что вы можете отменить голосование в удобное для вас время. :) - person Michael - sqlbot; 30.01.2017