Загрузка angular-файла с Amazon S3, получая метод 405, не разрешенный

У меня есть конечная точка amazon s3, в которую я пытаюсь загрузить файлы на стороне клиента (с некоторой серверной помощью).

Вот мой код политики:

s3Policy = JSON.stringify({
  expiration: '2038-12-01T12:00:00.000Z',
  conditions: [
    ["starts-with", "$key", filename], 
    { "bucket": bucket }, 
    { "acl": "public-read" },
    ["starts-with", "$Content-Type", (fileType || 'application/octet-stream')]
  ]
})

(Я кодирую его в base64 после этого)

Вот мой угловой запрос:

  var nameData = findExtension(file.name);
  $http({
    method: 'POST',
    url: '/project/' + projectId + '/files/gets3authorization',
    data: {
      fileType: file.type,
      fileExtension: nameData.extension
    }
  }).then(function(response) {
    var s3Data = response.data;
    Upload.upload({
      url: s3Data.bucketURL,
      method: 'POST',
      data: {
        key: s3Data.savedFileName,
        acl: 'public-read',
        "Content-Type": (file.type || 'application/octet-stream'),
        AWSAccessKeyId: s3Data.key,
        headers: { Authorization: undefined },
        Policy: s3Data.s3Policy,
        Signature: s3Data.s3Signature,
        filename: s3Data.savedFileName + '.' + nameData.extension,
        file: file
      }
    }).progress(function(evt) {
      var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
      $scope.log = 'progress: ' + progressPercentage + '% ' +
        evt.config.data.file.name + '\n' + $scope.log;
    }).success(function(data, status, headers, config) {
      $timeout(function() {
        $scope.log = 'file: ' + config.data.file.name + ', Response: ' + JSON.stringify(data) + '\n' + $scope.log;
      });
    }).error(function(err) {
      console.log("inner err: ", err)
    })
  }).catch(function(error) {
    console.log('outer err: ', error);
  });

Вот как выглядит моя политика (я собираюсь усилить безопасность после того, как POST начнут работать):

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "FileUpload",
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:PutObject",
    "Resource": "arn:aws:s3:::my_bucket/files*"
  }]
}

Вот мой конфиг CORS (опять же, ужесточение безопасности позже):

<?xml version="1.0" encoding="UTF-8" ?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>POST</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <ExposeHeader>x-amz-server-side-encryption</ExposeHeader>
    <ExposeHeader>x-amz-request-id</ExposeHeader>
    <ExposeHeader>x-amz-id-2</ExposeHeader>
    <AllowedHeader>*</AllowedHeader>
  </CORSRule>
</CORSConfiguration>

А вот и ответ от Chrome Tools

в Response Headers это включает POST, но Allow не включает это

Любая помощь очень ценится. Спасибо!

1 ответ

При размещении веб-сайта с помощью функции статического хостинга веб-сайта S3 вы можете использовать форму POST функция загрузки через браузер; однако конечная точка веб-сайта не принимает POST запрос, и ответим 405 Method Not Allowed, Это не проблема с разрешениями или CORS.

POST запросы принимаются только конечными точками REST. Для не-HTTPS запросов шаблон bucket-name.s3.amazonaws.com будет маршрутизироваться к конечной точке конкретного сегмента (но имя блока в подписанном документе политики остается bucket-name только без полного доменного имени).

Для запросов https, в которых имя целевого сегмента содержит одну или несколько точек, вам нужно будет использовать URL-адрес в виде пути для конечной точки REST, то есть https://s3[-region].amazonaws.com/bucket-name/ (иначе имя хоста не будет совпадать с сертификатом SSL подстановочного знака).

http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteEndpoints.html

http://docs.aws.amazon.com/general/latest/gr/rande.html

Другие вопросы по тегам