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