15

I am having problems serving static assets to Firefox using AWS Cloudfront.

Chrome works perfect, but Firefox is returning a CORS error.

If I execute curl , I get:

HTTP/1.1 200 OK
Content-Type: application/x-font-opentype
Content-Length: 39420
Connection: keep-alive
Date: Mon, 11 Aug 2014 21:53:50 GMT
Cache-Control: public, max-age=31557600
Expires: Sun, 09 Aug 2015 01:28:02 GMT
Last-Modified: Fri, 08 Aug 2014 19:28:05 GMT
ETag: "9df744bdf9372cf4cff87bb3e2d68fc8"
Accept-Ranges: bytes
Server: AmazonS3
Age: 2743
X-Cache: Hit from cloudfront
Via: 1.1 c445b20dfbf3128d810e975e5d84e2cd.cloudfront.net (CloudFront)
X-Amz-Cf-Id: ...

Which I think needs the header:

Access-Control-Allow-Origin: *

Can anyone help me? Why is it a problem on Firefox and not Chrome? How can I solve it?

18

First thing, you need to make sure that you whitelist origin header:

If you want CloudFront to respect cross-origin resource sharing settings, configure CloudFront to forward the Origin header to your origin.

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#request-custom-cors

Also see: http://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/

By the way, there are several similar questions on serverfault/stackoverflow and a lot of answers.

4

This is a bit more complicated than the accepted answer indicates.

The CORS support when using Cloudfront + S3 is actually implemented in S3 and it works like this according to Amazon:

The request's Origin header must match an AllowedOrigin element.

The request method (for example, GET or PUT) or the Access-Control Request-Method header in case the of a preflight OPTIONS request must be one of the AllowedMethod elements.

Every header listed in the request's Access-Control-Request-Headers header on the preflight request must match an AllowedHeader element.

This makes good sense, what may not be clear is that if no Origin header is sent by the client, then this processing isn't done at all. And we're using Cloudfront in front which, if you're just hosting static assets, you've probably set it up to ignore all headers when caching. Therefore if the first request to each file from a specific edge node doesn't include the Origin header, it will cache the response without the Access-Control-Allow-Origin header.

The result is that the first incoming request will determine which headers are returned for all requests until the cache expires.

There are several ways to fix/workaround this.

  • Setup cloudfront to do conditional caching based on the "Origin" header.

This works fine if you expect only a few or a single origin, but otherwise your caching ratio could become really bad.

  • Use Lambda@edge to forcibly set the headers, this can be done just once for each origin (S3) request.

Fully flexible, but adds overhead and cost.

  • Make cloudfront override the "Origin" header to a dummy value for every request.

This is only really useful in the "Access-Control-Allow-Origin: *" case and it's a bit of a hack, but it's probably the best current solution when hosting static assets on cloudfront + S3.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.