I am trying to use a webfont which I am legally permitted to use, but not to distribute. I am hosting the font files on a separate domain used for static content. The two domains are unrelated (one is not a subdomain of the other). Let’s say that the site using the webfont is example.com
and the site hosting it is example.net
.
I tried this in the .htaccess file on example.net
<FilesMatch "\.(ttf|otf|eot|woff|svg)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "example.com"
</IfModule>
</FilesMatch>
However, this allows the font to work only on the homepage of example.com
. I tried again:
Header set Access-Control-Allow-Origin "example.com/*"
Now the font works on example.com
everywhere except the homepage, which is (of course) not what I wanted.
I can’t find any documentation for this header. What I really want is to allow all pages on example.com
and www.example.com
(or, for good measure, *.example.com
). Is there a simple way to do this? I’m guessing that the header takes some kind of regex.
Looking for documentation I found,
I did not find any documentation about the syntax of the header itself, or how to specify variants of a domain.
Based on an answer to a related question, I tried this:
<FilesMatch "\.(ttf|otf|eot|woff|svg)$">
<IfModule mod_headers.c>
SetEnvIf Origin "http(s)?://(www\.)?(example.com)$" AccessControlAllowOrigin=$0$1
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Credentials true
</IfModule>
</FilesMatch>
My understanding was that this would set a separate header for each request, allowing each requesting page individually to use the font. Checking with Firebug, though, it looks like the header is always http://example.com
, both on the homepage and elsewhere. Nonetheless, this works, but leaves me confused. A related question shows that a similar setup was not working for someone else. His question suggests that for him, it actually was sending a different header for each requesting page, and that HTTP 304 Not Modified
responses were therefore breaking. His solution was to add an always
directive to the .htaccess
, but for me that resulted in HTTP 500
errors.
As it is now, it’s working, and I think will continue to work when example.com
switches to HTTPS (as it will shortly). However, I can’t help but feel that it’s overly complicated. It’s setting the same header each time, but is using complex pattern-matching to do so. Also, while I haven’t yet any problems with HTTP 304 Not Modified
responses (in fact, I’ve not yet seen any such responses: the browser simply doesn’t request the font files at all until I clear the cache), I worry that I might see them in future.
As stated by the CORS spec, you can have only one domain in the Access-Control-Allow-Origin
header (or *
or null
).
So yes, you need to set the header differently depending on what domain is requesting the site. That's why the apache config snippet you posted tries to match on the Origin
header of the request with this regex:
http(s)?://(www\.)?(example.com)$
The $
matches end of string. So this regex will match requests from http://www.example.com
, http://example.com
and their https equivalents, but not example.com/bla
. This should be fine since the Origin
header of the request, as well as the Access-Control-Allow-Origin
header of the response should contain only the host and not the subpages.
So when you're on the page http://example.com/about-us
, the browser will send something like the following request to get the font from http://cdn.net/myfont.otf
:
GET /myfont.otf HTTP/1.1
Host: http://cdn.net
Origin: http://example.com
There the server will patternmatch on the Origin header and return with:
Access-Control-Allow-Origin: http://example.com