title: Issue loading webfonts when served from AWS Cloudfront
body: <p>So, here's my conundrum! I have been trying to get Cloudfront to play nicely with my nginx server for the past three days...have read countless StackOverflow posts and blog articles...scoured the interwebs and I am still stuck with issues surrounding cross-domain access policies when it comes to Cloudfront serving fonts. I am going to post my complete setup in hopes that someone with more expertise may help me figure out what is going on. In the future, I hope this post will serve many others facing similar issues. <em>Here goes...</em></p>
  
  <h2>Nginx config:</h2>
  
  <p>I have a nginx webserver with the following server block configuration. <em>(...truncated for brevity)</em></p>
  
  <pre><code>    server {
          server_name  example.com www.example.com;
          root /var/www/example.com/html;
          index index.html index.htm;
  
          location / {
              try_files $uri $uri/ =404;
          }
          location /assets {
              autoindex on;
          }
  
          # Media
          location ~* \.(jpe?g|gif|png|ico|cur|gz|svgz?|mp4|ogg|ogv|webm|htc|webp)$ {
              expires 1M;
              access_log off;
              add_header Cache-Control public;
          }
  
          # Fonts
          location ~* \.(eot|ttf|woff|woff2|svg)$ {
              expires 365d;
              access_log off;
              add_header Cache-Control public;
              add_header Access-Control-Allow-Origin example.com;
              // Have also tried setting the "Access-Control-Allow-Origin" header to "*", but I'd prefer not to do this for security reasons.
          }
  
      }
  </code></pre>
  
  <p><strong>FYI: All of my website files I would like to serve and offload to CloudFront are in the <code>/assets</code> directory of my virtual host. <em>(ie. <a href="http://example.com/assets/." rel="nofollow">http://example.com/assets/.</a>.)</em></strong></p>
  
  <hr>
  
  <h2>CloudFront:</h2>
  
  <p>I have created a new CloudFront distribution with the following settings:</p>
  
  <p><strong><em>Note: I am not using S3 to host my website files and assets.</em></strong></p>
  
  <h3>General:</h3>
  
  <ul>
  <li>Alternate Domain Names (CNAMEs): <em>static.example.com</em></li>
  <li>Default Root Object: <em>index.html</em></li>
  </ul>
  
  <h3>Origins:</h3>
  
  <ul>
  <li>Origin Domain Name: <em>example.com</em></li>
  <li>Origin Path: <em>(left blank)</em></li>
  <li>Origin SSL Protocols: <em>TLSv1.2, TLSv1.1, TLSv1</em></li>
  <li>Origin Protocol Policy: <em>HTTP Only</em></li>
  <li>HTTP Port: <em>80</em></li>
  <li>HTTPS Port: <em>443</em></li>
  <li>Origin Custom Headers: <em>(none)</em></li>
  </ul>
  
  <h3>Behaviors:</h3>
  
  <ul>
  <li>Path Pattern: <em>Default (</em>)*</li>
  <li>Viewer Protocol Policy: <em>HTTP and HTTPS</em></li>
  <li>Allowed HTTP Methods: <em>GET, HEAD</em></li>
  <li>Cached HTTP Methods: <em>GET, HEAD (Cached by default)</em></li>
  <li>Forward Headers: <em>Whitelist</em>
  
  <ul>
  <li><em>Access-Control-Allow-Origin</em></li>
  </ul></li>
  <li>Object Caching: <em>Use Origin Cache Headers</em></li>
  <li>Forward Query Strings: <em>No (Improves Caching)</em></li>
  <li>Compress Objects Automatically: <em>Yes</em></li>
  </ul>
  
  <hr>
  
  <h2>DNS settings:</h2>
  
  <p>A portion of my Zone file...</p>
  
  <pre><code>example.com. 1800 IN A 12.34.567.890  //faked IP here for privacy reasons
  www.example.com. 1800 IN CNAME example.com.
  static.example.com. 1800 IN CNAME kg72kgf83nhfy3.cloudfront.net.  //faked CloudFront dist. domain name here for privacy reasons
  </code></pre>
  
  <hr>
  
  <h2>What's happening? Why it no- worky?</h2>
  
  <p>So, CloudFront does its thing processing and deploying my distribution, and I'm assuming pulling the assets from my <strong><em>'/assets/..'</em></strong> web directory. All <code>src</code>, <code>href</code>, and CSS <code>url()</code> references point to <strong><em><a href="http://static.example.com" rel="nofollow">http://static.example.com</a></em></strong> in my current HTML and CSS documents, including all <code>font-face</code> references. After the distribution is deployed, I hit my site <strong><em><a href="http://example.com" rel="nofollow">http://example.com</a></em></strong> in a browser.</p>
  
  <p>It appears that all static site assets are served correctly from CloudFront w/ appropriate caching headers as defined in my nginx config...<strong><em>EXCEPT</em></strong>...webfonts. I am getting missing fonts on the page and cross-domain access policy error messages in my browser console.</p>
  
  <h3>Headers—</h3>
  
  <ul>
  <li><p>An image, for reference <em>(when pinging my server)</em>:</p>
  
  <pre><code>curl -I "http://example.com/assets/images/image1.png"
  HTTP/1.1 200 OK
  Server: nginx/1.6.3
  Date: Sun, 15 May 2016 02:09:25 GMT
  Content-Type: image/png
  Content-Length: 194665
  Last-Modified: Sun, 15 May 2016 01:52:35 GMT
  Connection: keep-alive
  ETag: "5737d663-2f869"
  Expires: Tue, 14 Jun 2016 02:09:25 GMT
  Cache-Control: max-age=2592000
  Cache-Control: public
  Accept-Ranges: bytes
  </code></pre></li>
  <li><p>A font <em>(when pinging my server)</em>:</p>
  
  <pre><code>curl -I "http://example.com/assets/fonts/webfont.woff"
  HTTP/1.1 200 OK
  Server: nginx/1.6.3
  Date: Sun, 15 May 2016 02:10:29 GMT
  Content-Type: application/font-woff
  Content-Length: 8752
  Last-Modified: Sun, 15 May 2016 01:51:55 GMT
  Connection: keep-alive
  Vary: Accept-Encoding
  ETag: "5737d63b-2230"
  Expires: Mon, 15 May 2017 02:10:29 GMT
  Cache-Control: max-age=31536000
  Cache-Control: public
  Access-Control-Allow-Origin: example.com
  Accept-Ranges: bytes
  </code></pre></li>
  <li><p>Same image <em>(when requesting from CloudFront)</em>:</p>
  
  <pre><code>curl -I "http://static.example.com/assets/images/image1.png"
  HTTP/1.1 200 OK
  Content-Type: image/png
  Content-Length: 194665
  Connection: keep-alive
  Server: nginx/1.6.3
  Date: Sun, 15 May 2016 02:39:16 GMT
  Last-Modified: Sun, 15 May 2016 01:52:35 GMT
  ETag: "5737d663-2f869"
  Expires: Tue, 14 Jun 2016 02:39:16 GMT
  Cache-Control: max-age=2592000
  Cache-Control: public
  Accept-Ranges: bytes
  X-Cache: Miss from cloudfront
  Via: 1.1 lots_of_random_characters_i_dont_know_if_should_share_here.cloudfront.net (CloudFront)
  X-Amz-Cf-Id: lSM1plINYENbYycBn424LJ2wdtDhS3CpqAFiDSoxQDEctP_WM09bUQ==
  </code></pre></li>
  <li><p>Same font <em>(when requesting from CloudFront)</em>:</p>
  
  <pre><code>curl -I "http://static.example.com/assets/fonts/webfont.woff"
  HTTP/1.1 200 OK
  Content-Type: application/font-woff
  Content-Length: 8752
  Connection: keep-alive
  Server: nginx/1.6.3
  Date: Sun, 15 May 2016 02:41:00 GMT
  Last-Modified: Sun, 15 May 2016 01:51:55 GMT
  ETag: "5737d63b-2230"
  Expires: Mon, 15 May 2017 02:41:00 GMT
  Cache-Control: max-age=31536000
  Cache-Control: public
  Access-Control-Allow-Origin: example.com
  Accept-Ranges: bytes
  Vary: Accept-Encoding
  X-Cache: Miss from cloudfront
  Via: 1.1 lots_of_random_characters_i_dont_know_if_should_share_here.cloudfront.net (CloudFront)
  X-Amz-Cf-Id: vNfiyurS8pjosofnpLNSrnZuaGFg0V4xIs4ySCm05NKDMZ_PozhuOg==
  </code></pre></li>
  </ul>
  
  <p>Loading my website at <strong><em><a href="http://example.com" rel="nofollow">http://example.com</a></em></strong>, everything seems to work (ie. images) <em>EXCEPT</em> the webfonts. Checking the browser console outputs the following message for every font:</p>
  
  <blockquote>
    <p><em>Font from origin '<a href="http://static.example.com" rel="nofollow">http://static.example.com</a>' has been blocked from loading by Cross-Origin Resource Sharing policy: The 'Access-Control-Allow-Origin' header contains the invalid value 'example.com'. Origin '<a href="http://example.com" rel="nofollow">http://example.com</a>' is therefore not allowed access.</em></p>
  </blockquote>
  
  <p>So, anyone have any thoughts?? I would <em>greatly</em> appreciate the help/input. I'm a young web developer just trying to learn.</p>
  
  <p>Thank you! :)
  <br>–Kyle</p>
  
  <p><br></p>
  
  <hr>
  
  <p><em>Footnotes:</em></p>
  
  <ul>
  <li><a href="http://jmoiron.net/blog/serving-fonts-aws-cloudfront/" rel="nofollow">One of many blog posts</a> I've followed yet haven't been able to get things working.</li>
  <li>My plan is to append hashed query strings to the end of every file (ie. <code>//static.example.com/assets/images/image.png?622c6911</code>) to invalidate the CloudFront cache. This way I do not have to always re-upload new assets with changing names...I can simply control invalidation from the HTML and append a new query string to assets when I want CloudFront to request the latest version of that file from my webserver Origin.</li>
  <li>I will eventually be purchasing a SSL certificate for my site, so I would like traffic to support both HTTP and HTTPS requests.</li>
  </ul>