使用Amazon S3的angular-file-upload获取405方法不允许

时间:2015-11-20 01:12:01

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

我有一个亚马逊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>
&#13;
&#13;
&#13;

And here's response from chrome tools

Response Headers中,POST包含Allow,但int index = 0; while(rs.next()) { catOther[index][0]=rs.getInt("productId"); catOther[index][1]=rs.getString("productName"); catOther[index][2]=rs.getFloat("cost"); catOther[index][3]=rs.getString("trademark"); catOther[index][4]=rs.getString("description"); catOther[index][5]=rs.getString("category"); index++; } 不包含该内容。

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

1 个答案:

答案 0 :(得分:0)

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

只有REST端点接受

POST个请求。对于非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