No' Access-Control-Allow-Origin'使用Amazonaws S3在请求的资源上存在标头

时间:2016-09-04 08:18:11

标签: javascript python django amazon-s3 localhost

我有一个django应用程序并使用javascript直接将文件上传到s3桶后,在django后端签署上传所有这些都发生在我的localhost上。 问题是我得到一个错误:

XMLHttpRequest cannot load https://mybucket.s3.amazonaws.com/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5000' is therefore not allowed access.

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>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

客户端javascript在签名后上传文件

function uploadFile(file, s3Data, url){
          var xhr = new XMLHttpRequest();
          xhr.open("POST", s3Data.url);

          var postData = new FormData();
          for(key in s3Data.fields){
              console.log(key, s3Data.fields[key]) // the out put of this is bellow
            postData.append(key, s3Data.fields[key]);
          }
          postData.append('file', file);

          xhr.onreadystatechange = function() {
            if(xhr.readyState === 4){
              if(xhr.status === 200 || xhr.status === 204){
                alert("File uploaded.");
              }
              else{
                alert("Could not upload file.");
              }
           }
      };
      xhr.send(postData);
    } 

上面的console.log(key,s3Data.fields [key])的输出是

policy KJDLSKAFJLASKDFJLSAKDJFLKASJDFLKSAJDFLSKADJFLKSAJDFLKJSAD
Content-Type image/jpeg
acl public-read
signature lkjadflkjda
key add.jpg
AWSAccessKeyId LKAJDLKFJADFADD

注意:我修改了输出结果内容,而不是将其公开。

,文件对象是:

File {name: "add.jpg", lastModified: 1472705615906, lastModifiedDate: Thu Sep 01 2016 12:53:35 GMT+0800 (MYT), webkitRelativePath: "", size: 93156…}

django sign_s3函数,如果需要:

def sign_s3(request):
    S3_BUCKET = os.environ.get('AWS_STORAGE_BUCKET_NAME')
    file_name = request.GET.get('file_name')
    file_type = request.GET.get('file_type')
    s3 = boto3.client('s3')
    presigned_post = s3.generate_presigned_post(
        Bucket = S3_BUCKET,
        Key = file_name,
        Fields = {"acl": "public-read", "Content-Type": file_type},
        Conditions = [
            {"acl": "public-read"},
            {"Content_Type": file_type},
        ],
        ExpiresIn = 3600
    )
    return HttpResponse(json.dumps({
        'data': presigned_post,
        'url': 'https://%s.s3.amazonaws.com/%s' % (S3_BUCKET, file_name)
    }))
编辑:我在存储桶权限中玩过策略,现在我遇到了一个不同的错误:

我的政策是:

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

我得到的错误:

POST https://mybucket.s3.amazonaws.com/ 403 (Forbidden)
uploadFile @     
xhr.onreadystatechange @ 

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Invalid according to Policy: Policy Condition failed: ["eq", "$Content_Type", "image/jpeg"]</Message><RequestId>11EB24540D294B6F</RequestId><HostId>klasjdfl;skajdflksdjfl;ksdjf;lskdjfl;sakjdfl;skadjfl;skadjflsdkjfl;kdsajflksadjfl;ksajdf;lkadsjf</HostId></Error>

编辑2:从sign_s3函数中删除内容类型使我能够上传文件。我不明白为什么!

编辑3:解决了!我在sign_s3功能中输入了一个拼写错误,因为Condition中的content_type应该是content-type

0 个答案:

没有答案