I set up CORS on an S3 bucket like so:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>
Here's a screenshot of the AWS console: https://dzwonsemrish7.cloudfront.net/items/341y0o1n1X2a0O1X2s38/Screen%20Shot%202012-10-09%20at%209.59.44%20PM.png?v=2478ad83
When I point my color-thief javascript at an image hosted on the same domain, everything works as expected, but when I point to an asset in my S3 bucket, regardless of whether I run my script from localhost, lvh.me (which points to 127.0.0.1), or from the real interwebs, I get errors like this in Chrome 22:
Unable to get image data from canvas because the canvas has been tainted by cross-origin data.
Uncaught Error: SECURITY_ERR: DOM Exception 18
and this in Firefox 15:
SecurityError: The operation is insecure.
Here's what the headers look like in the Google Chrome Network Inspector:
Request URL:https://s3.amazonaws.com/assets-zeke.heroku.com/addons-zeke.heroku.com/catalogs/58/original.png
Request Method:GET
Status Code:304 Not Modified
Request Headers
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:s3.amazonaws.com
If-Modified-Since:Tue, 09 Oct 2012 22:52:57 GMT
If-None-Match:"6de1a52294934c5e288894b84100d99b"
Referer:http://localhost:5000/marketplace/addons/sendgrid/edit
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4
Response Headers
HTTP/1.1 304 Not Modified
x-amz-id-2: qGvoGlvpKeSSzelanWsIPDF3zd5wQzHTr27NZoUbhNqAM1QzmKcWHnTqIkKVxF/m
x-amz-request-id: FD24FB8CA244E327
Date: Wed, 10 Oct 2012 05:20:53 GMT
Last-Modified: Tue, 09 Oct 2012 22:52:57 GMT
ETag: "6de1a52294934c5e288894b84100d99b"
Server: AmazonS3
And here's what the headers look like after I changed the URL structure to {bucket}.s3.amazonaws.com
(and removed the period)
from my bucket name.
Request URL:http://assets-zeke.s3.amazonaws.com/addons-zeke.heroku.com/catalogs/58/original.png
Request Method:GET
Status Code:200 OK
Request Headers
Request Headers
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Host:assets-zeke.s3.amazonaws.com
Pragma:no-cache
Referer:http://lvh.me:5000/marketplace/addons/airbrake/edit
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4
Response Headers
Accept-Ranges:bytes
Content-Length:6696
Content-Type:image/png
Date:Wed, 10 Oct 2012 17:56:17 GMT
ETag:"6de1a52294934c5e288894b84100d99b"
Last-Modified:Wed, 10 Oct 2012 17:50:38 GMT
Server:AmazonS3
x-amz-id-2:UGVKQ9VQbJ82DLDxR53uDP0ZUMgla+e0GU5vO9yLr6MsY8wijl9KnM7fOyDlT+ta
x-amz-request-id:8A16CF1E02A0106C
Shouldn't I be seeing Access-Control-Allow-Origin: *
here? Does the 304 mean that Amazon is caching the response?
Confirm the cause of the error There are two ways to confirm the cause of a CORS error from API Gateway: Create an HTTP Archive (HAR) file when you invoke your API. Then, confirm the cause of the error in the file by checking the headers in the parameters returned in the API response.
In the Amazon S3 console, choose the bucket you want to edit. Select the Permissions tab, and scoll down to the Cross-origin resource sharing (CORS) panel. Choose Edit, and type your CORS configuration in the CORS Configuration Editor, then choose Save.
In the new (2020) S3 interface/dashboard, you need to write the header as a JSON. This code will fix the S3 Access-Control-Allow-Origin Header, allowing for GET requests from any domain. This code is placed in the Cross-origin resource sharing (CORS) section of the permissions tab for your specific bucket.
If the server is under your control, add the origin of the requesting site to the set of domains permitted access by adding it to the Access-Control-Allow-Origin header's value. You can also configure a site to allow any site to access it by using the * wildcard. You should only use this for public APIs.
This can be caused by not having enabled CORS in your image element before it has loaded:
imgEl.crossOrigin = '';
Request URL:https://s3.amazonaws.com/assets-zeke.heroku.com/addons-zeke.heroku.com/catalogs/58/original.png
Well, there's your problem. Because of the way that CORS and other cross-domain things work, you need to use DNS-style addressing to access your buckets.
Assuming your original URL is correct (it doesn't look like it, but I could totally be wrong), you'd want to use this URL instead:
http://assets-zeke.heroku.com.s3.amazonaws.com/addons-zeke.heroku.com/catalogs/58/original.png
In other words:
http://{bucket}.s3.amazonaws.com/path/object.ext
Check out: http://docs.amazonwebservices.com/AmazonS3/latest/dev/cors.html for more explanation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With