How to add an Access-Control-Allow-Origin header
Asked Answered
S

5

109

I am designing a website (e.g. mywebsite.example) and this site loads font-face fonts from another site (say anothersite.example). 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?

Spinelli answered 15/2, 2011 at 20:10 Comment(1)
S
179

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)

Spinelli answered 15/2, 2011 at 20:28 Comment(9)
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.Decuple
This solution is also valid for cross domain .ajax requests !! Nice!Er
@StrayObject - the remote CSS file will need to use the full paths. The local CSS file does not have to.Spinelli
It is apparently not possible to whitelist multiple URLs, comma-delimited or otherwise; see bug 671608Viewer
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)$").Adduce
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.Houseyhousey
This answer (stackoverflow.com/a/4110601) seems to suggest that a comma separated list doesn't workNobleminded
That you have to put this in the folder where the fonts are, vs. the root .htaccess, seems to be key.Ciliate
this given code works for apache, any suggestion for Nginx server - @Spinelli thanks in advanceNeotropical
O
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.

Ornithopter answered 30/7, 2013 at 17:40 Comment(3)
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 siteBackflow
@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)Dichy
For some reasons, HTTP_ORIGIN isn't set for me, I had to add this line SetEnvIfNoCase Origin (.+) HTTP_ORIGIN=$1.Contradistinguish
U
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>
Ulrikaumeko answered 15/1, 2014 at 19:27 Comment(0)
B
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).

Buskin answered 27/3, 2014 at 19:38 Comment(0)
C
2

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

<?php header('Access-Control-Allow-Origin: *'); //for all ?>
Champlin answered 3/9, 2015 at 13:11 Comment(1)
This worked for me. Very simple. No need to mess with apache config or restarts.Mastoiditis

© 2022 - 2024 — McMap. All rights reserved.