Amazon-web-services – AWS S3 + CloudFront gives CORS errors when serving images from browser cache

amazon s3amazon-cloudfrontamazon-web-servicescors

If I clear my browser cache, everything loads just find from my cloudfront-enabled S3 bucket. When I turn off cache, however, I get errors in the console:

Image from origin [ORIGIN URL] has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin [MY LOCALHOST ADDRESS] is therefore not allowed access.

MY CORS configuration:

<?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>

I also followed this advice a while back and changed the cloundfront distro settings. It seemed to have worked back then but is definitely not working with browser cache now:
CORS problems with Amazon S3 on the latest Chomium and Google Canary

I also tried putting "Header add Access-Control-Allow-Origin "*"" in my websites .htaccess. No luck. Note: my website is hosted and accessed from localhost (it's a dev environment).

Best Answer

I found myself with the same sort of problem: no Access-Control-Allow-Origin coming up. It was very random, sometimes it worked, other times it did not. I finally narrowed it down in this way:

  1. Turned on S3 website hosting
  2. Tested for CORS header in both S3 and CloudFront

Here is how to easily test for a CORS header:

curl -i -H "Origin: http://YOUR-SITE-URL" http://S3-or-CLOUDFRONT-URL | grep Access

In my case it would work fine in S3, but in CloudFront it will only sometimes return back the access-control headers:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000

After more research, I discovered that our CloudFront distribution was configured to block the headers from going to S3. To fix this:

  1. Go to CloudFront distribution in the AWS dashboard
  2. Click on Distribution Settings
  3. Click on the Behaviors Tab
  4. Edit the default pattern Behavior
  5. Click on Forward Headers and select Whitelist
  6. Add the 3 suggested headers: Access-Control-Request-Headers, Access-Control-Request-Method, Origin
  7. Save changes

Once the headers made it to S3, we could always see the correct access control information with curl command above.