7 May 2013


by mo

Cross-Origin Resource Sharing is a way for web applications that are hosted at one domain to access resources hosted in a different domain.

For example:

If http://blah.com/ wants to use a webfont that is served up through http://blah.cloudfront.net then an Access-Control-Allow-Origin header needs to be returned with the resource with a value of http://blah.com/. If not, Firefox will not load the web font. Chrome and Safari don’t seem to care. This is actually trickier than it sounds.

On a site we have been working on recently, we host our pre-compiled assets as well as any digital uploads in an AWS S3 bucket. We use CloudFront with a distribution that points to that bucket to distribute the static asssets. In order to get the proper Access-Control-Allow-Origin header to be returned you must setup some CORS rules on your S3 bucket.

CORS Configuration

  1. Log in to the AWS console.
  2. Navigate to the S3 dashboard.
  3. Choose your S3 bucket.
  4. Click on Properties.
  5. Choose the Permissions section.
  6. Click on “Edit CORS Configuration”
  7. Enter the following rules.
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">

The AWS documentation suggests that you can upload a “cors” file to the root of your bucket to configure rules, but I could not get this to work.

You can test your configuration using curl.

$ curl -i -H "Origin: https://blah.com" -svk -o /dev/null https://blah.cloudfront.net/assets/font.eot

If it works you in the response you should see:

  Access-Control-Allow-Origin: http://blah.com

But it’s not over. If the first request to the cloudfront resource is for an http request then cloudfront will cache the response header as http. If the next request is for the same resource using https, then you will get the same cached http header back. This will cause Firefox to not load your webfont.

If you choose to hit your s3 bucket directly this is not an issue as headers are not cached. I have found that serving the font using https directly from the s3 bucket seems to be the easiest solution so far.