Как загружать файлы в AWS-S3 с помощью Angular $ http PUT

В моем приложении Angular я пытаюсь загрузить файл на AWS-S3 с помощью $http.put(url, file).

Однако это не работает, я получаю HTTP-403 Forbidden, сообщающий мне, что рассчитанная подпись s3 отличается от той, которую я предоставил, НО если я сделаю тот же запрос с помощью curl, например curl -X PUT -T file url, тогда все в порядке, файл будет загружен. Так что либо $ http.put работает плохо (для этой задачи), либо curl имеет некоторую магию. Кто-нибудь может уточнить?


person Jim-Y    schedule 04.01.2017    source источник
comment
Вы проверяли stackoverflow.com/questions/2777078?   -  person LS_ᴅᴇᴠ    schedule 04.01.2017
comment
Я проверил сейчас, но ни один из ответов не относится к моему случаю. С помощью curl я могу заставить его работать, но не с помощью $ http: /   -  person Jim-Y    schedule 04.01.2017


Ответы (2)


При загрузке файла с помощью службы $ http важно установить Content-Type: undefined.

  var config = { headers: {
                   "Content-Type": undefined,
                  }
               };

  var promise = $http.put(url, file, config);

Тип содержимого по умолчанию для службы $ http - application/json. При установке Content-Type: undefined служба $ http пропускает заголовок Content-Type, а API XHR устанавливает заголовок Content-Type равным заголовку файла.

person georgeawg    schedule 04.01.2017

К вашему сведению:

Так и не узнал почему $http не работает .. даже странные вещи по этой теме находил.

Итак, сначала я "извлек" файл из html следующим образом:

<input flex="40" type="file" onchange="angular.element(this).scope().$parent.selectAttachment(this)">

потому что я не хотел создавать директиву для этой цели тестирования. Функция selectAttachment просто устанавливает файл как свойство для моего контроллера.

Тогда вроде бы все было нормально, я мог читать, например, this.attachment.name или this.attachment.size, но когда я написал $http.put(url, this.attachment), я получил ошибку несоответствия подписи.

Затем я попробовал то же самое с XHR, как в этом руководстве: https://devcenter.heroku.com/articles/s3-upload-node

Никогда не везет ...

Затем, в крайнем случае, я попытался получить файл, установив его не через angular, а через const file = document.getElementById('report-attachment').files[0];, и, наконец, у меня это сработало. Интересно, что получение файла с getElementById И с использованием $ http по-прежнему не работает, ни 1, ни 2 сторонних угловых загрузчика, которые я пробовал, только с XHR o.o

Окончательное «решение», которое мне подходит:

HTML:

<input flex="40" id="report-attachment" type="file">

JS:

            const file = document.getElementById('report-attachment').files[0];
            const url = r && r.data;
            const xhr = new XMLHttpRequest();
            xhr.open('PUT', url);
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                        console.debug('success');
                    } else {
                        console.error('error');
                    }
                }
            };
            xhr.send(file);
person Jim-Y    schedule 04.01.2017