104

I am designing a website (e.g. mywebsite.com) and this site loads font-face fonts from another site (say anothersite.com). I was having problems with the font face font loading in Firefox and I read on this blog:

Firefox (which supports @font-face from v3.5) does not allow cross-domain fonts by default. This means the font must be served up from the same domain (and sub-domain) unless you can add an “Access-Control-Allow-Origin” header to the font.

How can I set the Access-Control-Allow-Origin header to the font?

sideshowbarker
  • 62,215
  • 21
  • 143
  • 153
Mazatec
  • 10,573
  • 23
  • 65
  • 106

5 Answers5

168

So what you do is... In the font files folder put an htaccess file with the following in it.

<FilesMatch "\.(ttf|otf|eot|woff|woff2)$">
  <IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
  </IfModule>
</FilesMatch>

also in your remote CSS file, the font-face declaration needs the full absolute URL of the font-file (not needed in local CSS files):

e.g.

@font-face {
    font-family: 'LeagueGothicRegular';
    src: url('http://www.example.com/css/fonts/League_Gothic.eot?') format('eot'),
         url('http://www.example.com/css/fonts/League_Gothic.woff') format('woff'),
         url('http://www.example.com/css/fonts/League_Gothic.ttf') format('truetype'),
         url('http://www.example.com/css/fonts/League_Gothic.svg')

}

That will fix the issue. One thing to note is that you can specify exactly which domains should be allowed to access your font. In the above htaccess I have specified that everyone can access my font with "*" however you can limit it to:

A single URL:

Header set Access-Control-Allow-Origin http://example.com

Or a comma-delimited list of URLs

Access-Control-Allow-Origin: http://site1.com,http://site2.com

(Multiple values are not supported in current implementations)

Waheed
  • 528
  • 3
  • 19
Mazatec
  • 10,573
  • 23
  • 65
  • 106
  • 1
    You do not have to use full paths. Simple `url('/fonts/League_Gothic.woff') format('woff')` is enough assuming you keep the 'fonts' folder in the same dir as your .css file. – StrayObject Dec 14 '11 at 14:03
  • 1
    This solution is also valid for cross domain .ajax requests !! Nice! – Isaac Dec 14 '11 at 15:20
  • 3
    @StrayObject - the remote CSS file will need to use the full paths. The local CSS file does not have to. – Mazatec Dec 16 '11 at 16:05
  • It is apparently not possible to whitelist multiple URLs, comma-delimited or otherwise; see [bug 671608](https://bugzilla.mozilla.org/show_bug.cgi?id=671608) – Tgr Jan 10 '13 at 13:38
  • Your css files need to be served with `Access-Control-Allow-Origin` too since its the source file that designates what external resources can be loaded (`"\.(ttf|otf|eot|woff|css)$"`). – Kevin Stone Sep 07 '13 at 19:30
  • I tried to use this on tumblr and did it as said here [I made a free web hosted site to get htaccess thing and all] and it didn't work. – MSmS Nov 09 '13 at 13:58
  • 1
    This answer (http://stackoverflow.com/a/4110601) seems to suggest that a comma separated list doesn't work – Asaf Nov 12 '13 at 13:23
  • Your answer has proven invaluable. Thank you! – Terra Ashley Jun 20 '14 at 10:22
  • That you have to put this in the folder where the fonts are, vs. the root .htaccess, seems to be key. – Nathan Jul 07 '20 at 15:46
21

According to the official docs, browsers do not like it when you use the

Access-Control-Allow-Origin: "*"

header if you're also using the

Access-Control-Allow-Credentials: "true"

header. Instead, they want you to allow their origin specifically. If you still want to allow all origins, you can do some simple Apache magic to get it to work (make sure you have mod_headers enabled):

Header set Access-Control-Allow-Origin "%{HTTP_ORIGIN}e" env=HTTP_ORIGIN

Browsers are required to send the Origin header on all cross-domain requests. The docs specifically state that you need to echo this header back in the Access-Control-Allow-Origin header if you are accepting/planning on accepting the request. That's what this Header directive is doing.

laughingbovine
  • 452
  • 5
  • 11
  • 2
    that seems to work for me too, although it seems to have the side effect of needing to clear your cache if you visit two different sites that access the site – Jack James Jul 31 '13 at 11:17
  • 1
    @Jack: yeah, it's a big one for CDN content (looking at you, font files). Depending on caching settings, you could end up with file contents and an incorrect CORS header persisting locally (as in your scenario) or on proxy! (cache-busting with `?yourdomain` works in the latter case, but devalues the benefits of using a CDN a bit) – Oleg Nov 18 '13 at 20:44
  • 2
    For some reasons, HTTP_ORIGIN isn't set for me, I had to add this line ```SetEnvIfNoCase Origin (.+) HTTP_ORIGIN=$1```. – David Riccitelli Apr 13 '14 at 09:02
5

For Java based Application add this to your web.xml file:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.ttf</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.otf</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.eot</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.woff</url-pattern>
</servlet-mapping>
Michael
  • 5,910
  • 4
  • 52
  • 74
Neon Sun
  • 51
  • 1
  • 1
5

The accepted answer doesn't work for me unfortunately, since my site CSS files @import the font CSS files, and these are all stored on a Rackspace Cloud Files CDN.

Since the Apache headers are never generated (since my CSS is not on Apache), I had to do several things:

  1. Go to the Cloud Files UI and add a custom header (Access-Control-Allow-Origin with value *) for each font-awesome file
  2. Change the Content-Type of the woff and ttf files to font/woff and font/ttf respectively

See if you can get away with just #1, since the second requires a bit of command line work.

To add the custom header in #1:

  • view the cloud files container for the file
  • scroll down to the file
  • click the cog icon
  • click Edit Headers
  • select Access-Control-Allow-Origin
  • add the single character '*' (without the quotes)
  • hit enter
  • repeat for the other files

If you need to continue and do #2, then you'll need a command line with CURL

curl -D - --header "X-Auth-Key: your-auth-key-from-rackspace-cloud-control-panel" --header "X-Auth-User: your-cloud-username" https://auth.api.rackspacecloud.com/v1.0

From the results returned, extract the values for X-Auth-Token and X-Storage-Url

curl -X POST \
  -H "Content-Type: font/woff" \
  --header "X-Auth-Token: returned-x-auth-token" returned-x-storage-url/name-of-your-container/fonts/fontawesome-webfont.woff

curl -X POST \
  -H "Content-Type: font/ttf" \
  --header "X-Auth-Token: returned-x-auth-token" returned-x-storage-url/name-of-your-container/fonts/fontawesome-webfont.ttf

Of course, this process only works if you're using the Rackspace CDN. Other CDNs may offer similar facilities to edit object headers and change content types, so maybe you'll get lucky (and post some extra info here).

Phil
  • 2,689
  • 1
  • 20
  • 29
1

In your file.php of request ajax, can set value header.

<?php header('Access-Control-Allow-Origin: *'); //for all ?>
Santos L. Victor
  • 597
  • 5
  • 12