【问题标题】:angular-file-upload with Amazon S3 getting 405 Method Not Allowed使用 Amazon S3 的 angular-file-upload 获取 405 Method Not Allowed
【发布时间】:2015-11-20 01:12:01
【问题描述】:

我有一个亚马逊 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>

And here's response from chrome tools

Response Headers 中包含POST,但Allow 不包含它。

非常感谢任何帮助。谢谢!

【问题讨论】:

  • 您不能将POST 请求直接发送到托管在 S3 中的网站,因为网站端点不接受它们。您必须向存储桶的 REST 端点发送 POST 请求;对于非 HTTPS,主机名 bucket-name.s3.amazonaws.com 应该始终有效。对于 HTTPS,需要不同的区域特定排列。
  • 通过该更改,我在 POST 之后收到此错误:Invalid according to Policy: Policy Condition failed: ["eq", "$bucket", "stub-19.s3.amazonaws.com"]。我的签名桶和角度 POST 桶都定义为[BUCKET].s3.amazonaws.com。我忽略了/files 部分只是为了让主要功能正常工作
  • 从帖子策略中的存储桶名称中删除 .s3.amazonaws.com
  • 太棒了——它成功了!谢谢你的帮助!!

标签: angularjs amazon-web-services amazon-s3 angular-file-upload ng-file-upload


【解决方案1】:

当使用 S3 的 static web site hosting 功能托管网站时,您可以使用表单 POST browser-based upload 功能;但是,网站端点不接受POST 请求,并将以405 Method Not Allowed 响应。这不是权限或 CORS 问题。

POST 请求仅被 REST 端点接受。对于非 HTTPS 请求,模式 bucket-name.s3.amazonaws.com 将路由到特定存储桶的端点(但签名策略文档中的存储桶名称仅保留 bucket-name,没有完整的域名)。

对于目标存储桶名称中包含一个或多个点的 https 请求,您需要为 REST 端点使用路径样式的 URL,即 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#s3_region

【讨论】:

    猜你喜欢
    • 2023-03-18
    • 2021-04-24
    • 2021-06-20
    • 2016-04-12
    • 1970-01-01
    • 2019-10-05
    • 2018-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多