I am using an S3 bucket behind Cloudfront with CORS enabled. If the client makes a request with the Origin header, then S3 (and cloudfront) respond with a "Vary: Origin" header, however if the request is made without the Origin, header then the response does not contain any Vary Header.
This is problematic because I use a resource from cloudfront/s3 in an img tag, in which case the browser makes the request without the Origin header, and then later make an ajax request for said image. The browser then uses the cached version of the image, without the Access-Control-Allow-Origin header, and therefore denies the request.
Is there any way to get S3 to always return the "Vary: Origin" header?
CORS is a feature of HTTP that uses headers to allow browsers to display content which a web server requested from a different origin. If you make a cross-origin request to an Amazon S3 bucket that isn't defined by a CORS rule, then the CORS header isn't returned.
Sign in to the AWS Management Console and open the Amazon S3 console at https://console.aws.amazon.com/s3/ In the Buckets list, open the bucket whose properties you want to view and click "add CORS configuration" Write the rules you are willing to add in between the tags <CORSConfiguration>
Cross-origin resource sharing (CORS) defines a way for client web applications that are loaded in one domain to interact with resources in a different domain. With CORS support, you can build rich client-side web applications with Amazon S3 and selectively allow cross-origin access to your Amazon S3 resources.
I made an account just to answer your question, because there are very few good answers around for this kind of problem (and a few related ones).
The problem you describe happens for some reason primarily in chrome, FF and IE seems to be smart enough not to share cache between AJAX and regular calls in these instances.
Lets first describe why the problem happens for future readers:
<img>
or <script>
tag. If the server is in the same domain it does not includes an CORS headers.In HTML5 there is an attribute called crossorigin
that can be added to tags to signify that they need to send origin information. Possible values are crossorigin='anonymous'
and crossorigin='use-credentials'
these are quite irrelevant to the question asked but as it says in the documentation:
By default (that is, when the attribute is not specified), CORS is not used at all.
https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes
So just create your image tags like this <img src='cloundfront.path' crossorigin='use-credentials'>
Thats it. Its quite obscure so I hope that this answer saves some research time to a bunch of people.
Another solution would be configuring your CloudFront distribution to automatically turn Non-CORS requests into CORS requests. This is possible by adding a CORS header to each request CloudFront sends to S3 using the recently added CloudFront feature "Control Edge-To-Origin Request Headers".
See the feature announcement here: https://aws.amazon.com/blogs/aws/cloudfront-update-https-tls-v1-1v1-2-to-the-origin-addmodify-headers/
And the documentation here: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/forward-custom-headers.html.
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