Reputation: 10745
I'm storing JSON objects in Amazon S3, and I'd like to load that data directly from S3 from Javascript. My GET looks pretty generic:
$.ajax({
'type':'GET',
'url':'http://s3.amazonaws.com/mybucketname/'+id,
'dataType':'text',
'success':function(msg) {
alert(msg);
}
});
I get the following error:
XMLHttpRequest cannot load http://s3.amazonaws.com/whatever/whatever. Origin http://mylocalhostname:9000 is not allowed by Access-Control-Allow-Origin.
I can get that URL from S3 using curl, or by navigating there directly from my browser. Am I really going to have to proxy all of these requests through my own servers?
Upvotes: 38
Views: 48951
Reputation: 421
For my case, I want to GET some resources from a bucket "myBucket".
On the S3 client side, AWS S3 now support JSON to configure CORS policies [ref]
Bucket Policy:
[
{
"AllowedHeaders": [
"*",
"x-amz-*"
],
"AllowedMethods": [
"GET",
"HEAD"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
On server-side / client side (JQUERY Ajax)
$.ajax({
type: "GET",
url: "https://myBucket/myObject",
});
Try it!, hope it helps!
Upvotes: 0
Reputation: 4354
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
This CORS configuration worked like a charm
Upvotes: 1
Reputation: 1
For anyone struggling with this issue, as others say you must force S3 to respond with CORS headers by adding these lines to your CORS configuration:
<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>
BUT, you then must clear your browser file cache as the old headers on the requested resource are stored. In Chrome, find the Clear Browsing Data option and then choose to clear the file cache. A hard reload will not clear certain files. If you prefer to only clear the file cache only for the current site, this answer explains how to do just that.
This was the gotcha for me.
Upvotes: 0
Reputation: 1065
You may want to increase the MAX AGE configuration if you have larger files that will take longer to download, or they may cut off early. Media hosting etc will need this. My config for wildcard access (any domain) was 10000 seconds max, which should be safely longer than anyone needs to download my files even on a bad connection:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<MaxAgeSeconds>10000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Upvotes: 0
Reputation: 14227
We had a similar problem, but not with GET but with presigned S3 POST. I thought this may be helpful for someone googling this issue.
in some browsers Dropzone.js lib was not able to upload images directly to S3 bucket (presigned S3 POST). Weird part was that this was happening on some computers all the time and on some one out of twenty tries.
On one computer we manage to capture the error in Firefox Debugger (network tab)
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://s3-eu-west-1.amazonaws.com/pobble.com-browser-uploads-production. (Reason: CORS header 'Access-Control-Allow-Origin' missing).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://s3-eu-west-1.amazonaws.com/pobble.com-browser-uploads-production. (Reason: CORS request failed).
Updating the S3 bucket CORS to this worked for us:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://www.myapp.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
<ExposeHeader>Accept-Ranges</ExposeHeader>
<ExposeHeader>Content-Range</ExposeHeader>
<ExposeHeader>Content-Encoding</ExposeHeader>
<ExposeHeader>Content-Length</ExposeHeader>
<ExposeHeader>Access-Control-Allow-Origin</ExposeHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>https://www.app.com</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
<ExposeHeader>Accept-Ranges</ExposeHeader>
<ExposeHeader>Content-Range</ExposeHeader>
<ExposeHeader>Content-Encoding</ExposeHeader>
<ExposeHeader>Content-Length</ExposeHeader>
<ExposeHeader>Access-Control-Allow-Origin</ExposeHeader>
</CORSRule>
</CORSConfiguration>
important part is the <ExposeHeader>Access-Control-Allow-Origin</ExposeHeader>
thanks to this S3 is exposing response header OPTIONS
and POST
Collaborative work of @anas-alaoui, @joserose & @equivalent
Upvotes: 5
Reputation: 438
S3 now supports Cross Domain Requests using CORS file.
You can find more information here:
http://docs.amazonwebservices.com/AmazonS3/latest/dev/cors.html#how-do-i-enable-cors
and:
http://aws.typepad.com/aws/2012/08/amazon-s3-cross-origin-resource-sharing.html
Upvotes: 40
Reputation: 1
This is my Tip from: https://github.com/mozilla/pdf.js/issues/3150
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
<ExposeHeader>Accept-Ranges</ExposeHeader>
<ExposeHeader>Content-Range</ExposeHeader>
<ExposeHeader>Content-Encoding</ExposeHeader>
<ExposeHeader>Content-Length</ExposeHeader>
</CORSRule>
</CORSConfiguration>
Upvotes: 0
Reputation: 5533
S3 doesn't send the 'Access-Control-Allow-Origin' header if you use the wildcard * like:
<AllowedOrigin>*</AllowedOrigin>
To force s3 sending the AllowedOrigin header but still let your content be loaded from any site, use this:
<AllowedOrigin>http://*</AllowedOrigin>
<AllowedOrigin>https://*</AllowedOrigin>
Upvotes: 43
Reputation: 88
I was struggling with the same sort of issue. only difference is i wanted to pull a file with Ajax from my S3 and load it into a site.
After a lot of searching i ended up adding this option to my Ajax request.
Worked like a charm, as long as you have the CORSConfiguration to allow all.
hope it helps.
Upvotes: 1
Reputation: 6764
Searched a lot - This is the sample solution:
http://blog.bignerdranch.com/1670-upload-directly-to-amazon-s3-with-support-for-cors/
(Add cors on bucket permissions tab)
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Upvotes: 6
Reputation: 1846
You can use a jsonp request instead of json. Here are the details. http://api.jquery.com/jQuery.ajax/
Upvotes: 3