AWS S3 + CloudFront gives CORS errors when serving images from browser cache
Solution 1
I was stuck in the same problem and found that exposing headers as shown below solve the problem:
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>MYIP</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<ExposeHeader>ETag</ExposeHeader>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
Solution 2
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:
- Turned on S3 website hosting
- 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:
- Go to CloudFront distribution in the AWS dashboard
- Click on Distribution Settings
- Click on the Behaviors Tab
- Edit the default pattern Behavior
- Click on Forward Headers and select Whitelist
- Add the 3 suggested headers: Access-Control-Request-Headers, Access-Control-Request-Method, Origin
- Save changes
Once the headers made it to S3, we could always see the correct access control information with curl command above.
Chris Scott
Updated on June 06, 2022Comments
-
Chris Scott almost 2 years
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).
-
Anurag Pratap over 8 yearsMYIP format: for my local development machine I used : localhost:3000 as it specifies origin from where request is triggering.
-
Chris Scott over 8 yearsOddly the problem spontaneously stopped happening (before I implemented this solution). But I will try this if it starts acting up again.
-
Chris Scott over 8 yearsI had the problem again, implementing your solution and it seems to have worked. I marked your answer as correct. Thank you!
-
Chris Scott over 8 yearsSpoke to soon. I am getting the errors again. Are there other tags I should include, other than, ExposeHeader?
-
Anurag Pratap over 8 yearsI don't think any other tag is required.Please ensure following things: * Format of origin is not correct. * You specify CORS for each bucket you are using.
-
Chris Scott over 8 yearsCan you elaborate on what you mean by "Format of origin is not correct"?
-
Eduardo Almeida over 6 yearsProbably this is the most complete answer regarding this topic on Stackoverflow, but it's still not working for me. It seems that Cloudfront only Forward Headers from my Subdomains (eg.: www.myapp.com), but it doesn't to my domain (myapp.com) - if anyone knows why have a look here: stackoverflow.com/questions/45528115/…
-
Matt Dodge about 6 yearsI had to add
Access-Control-Allow-Origin
andAccess-Control-Allow-Methods
to the headers but this approach worked. Basically, you need to include the headers that you are sending in your pre-flight requests to be passed through the cloudfront distribution. Great answer, thank you! -
Matt Dodge about 6 yearsAlso FYI, the section isn't called "Forward Headers" anymore, it's now "Cache Based on Selected Request Headers" then select "Whitelist"
-
BrunoLM almost 5 yearsThis doesn't always work for me, I have been having this issue for weeks now, sometimes the images don't load and I see a CORS error on the console. It's not easy to reproduce this bug.
-
Todd about 4 yearsThanks for the ETag header exposure that did the trick for me. I saw it in the documentation somewhere but was unable to locate it again. I would like to point out in your example code you have the "<AllowedMethod>PUT</AllowedMethod>" twice. Maybe one should be "<AllowedMethod>GET</AllowedMethod>"?