I have a simple django app on heroku for uploading images and it works as expected when accessed from desktop but fails to sign the requests for upload to AWS S3 when I access the site on mobile.
The signing code is shown below:
def sign_s3(request):
request = request.GET
S3_BUCKET = os.environ.get('AWS_STORAGE_BUCKET_NAME')
file_name = request.get('file_name')
file_type = request.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)
}))
I set everything in the S3 bucket to public and have the CORS set as
<?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>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
This is a sample of the javascript used to send the request. I have realised it doesnt seem to send at all when its on mobile. The status code comes out as 0.
function getSignedRequest(file){
var xhr = new XMLHttpRequest();
xhr.open("GET", "/sign_s3?file_name="+file.name+"&file_type="+file.type);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status === 200){
var response = JSON.parse(xhr.responseText);
uploadFile(file, response.data, response.url);
}
else{
alert("Could not get signed URL.");
}
}
};
xhr.send();
}
uploadFile is just a separate function that finally posts the image.
I cant tell what could be causing this difference. How can I get this working?