Many WordPress sites, web fonts, CORS

Alphabet

So this bug has plagued us from the very beginning: sometimes, members of the dev team would notice that our nice web font and custom icon font would not load. The web font would fall back to a system font so most folks never notice this. The icon font didn’t have a fallback, though, so it would render little boxes where icons should be. Annoying!

We noticed that it never seemed to happen in IE, so we figured that the reason only the team ever noticed it was because most other users use IE around here.

Our business contact finally complained about it. She had started using Chrome more often and had started noticing the issue with the icons. Today I finally set about getting to the bottom of this thing for once and all.

Here is what I found. It’s complicated, so I will tell you in story form.

How to trigger the bug… a story of many WordPress installs.

It’s Monday and I come in to find that Sarah has sent out a QA request – her story code is on alpha.oursite.sas.com. I visit alpha to QA her story. The fonts all load great.

Then I go to my playpen, lisa.oursite.sas.com, to work on my own story. The fonts don’t load! When I hit reload, they load and everything is fine while I am working.

Then Sarah, who is really quick sometimes, sends out another QA request. She has another story out on alpha. When I visit alpha, the font doesn’t load!

 

What is actually happening in the browser?

When I come in on Monday and visit alpha, my browser cache has expired, so it doesn’t attempt to load the font files from cache. It successfully loads them from their original source, which is actually another domain on our intranet (for the fonts), and our external web site (for the icons).

After that, while still on alpha, my browser happily loads the fonts from the BFCache (in the case of Firefox – that’s the “Backwards / Forwards Cache“). Firebug shows a response code of 200 OK, and the Firebug docs say that that’s because that was the original response code that went into the cache. (You might expect it to be the response code for loaded from cache, which is I think 304, but it’s not. Try not to get confused by this, okay?)

When I then visit my playpen while my browser cache is still valid and hasn’t expired, the browser tries to load the files from BFCache and although no 404 shows in the Net panel of Firefox, clearly, it fails to load.  The key to understanding what’s happening is a message in the console:

(Reason: CORS header 'Access-Control-Allow-Origin' does not match 'http://lisa.oursite.sas.com').
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote 
resource at http://www.sas.com/icons.ttf. (Reason: CORS header 'Access-Control-Allow-Origin' 
does not match 'http://alpha.oursite.sas.com').

So it appears that the headers need to have a match between the site that originally loaded the font file into the BFCache and the site that’s requesting the font file. When they don’t match, the font file doesn’t load. When I reload my browser, I force it to load the file from the original source and that succeeds, and updates the cache. When I visit another one of our sites, the headers again don’t match and the font doesn’t load.

If I am correct about this, I believe that only members of our team, and only those members who use browsers other than IE, will ever see this problem – we’re the only people who visit the various dev, test, and content staging sites. Which is good, because I think the best solution (if we need one) would be to force the browser not to use the cached font on all but our live site, and that would be a pain to implement (if even possible).

 

A little light reading about web fonts, CORS, and how they interact

If you want to better understand CORS (“cross-origin resource sharing”) and how it affects font loading, here are some helpful articles: