Sunday, July 25, 2010

Fixing Firefox font-face Cross Domain Problem

On a recent post I used a web font via the @font-face CSS directive. When viewed from Firefox it was working fine on my local development machine, but not from my Blogger post. Here's what I was using locally:
@font-face {
    font-family:'GraublauWeb';
    src:url(GraublauWeb.otf) format("opentype");
}
And here's what I used for my post:
@font-face {
    font-family:'GraublauWeb';
    src:url(http://pics.cssbakery.com/fonts/GraublauWeb.otf) format("opentype");
}
As it turns out, Firefox was blocking the use of the font since my post is served from www.cssbakery.com, and the font is on a different sub-domain, pics.cssbakery.com. Firefox intentionally blocks fonts from different domains, as a measure of protection against someone just linking in your fonts, effectively stealing your server bandwidth and possibly violating the font's EULA.

In my case, serving the font from the same domain as my post isn't an option (unless I jump ship from Blogger and self host my blog). But, there is a way for the Web Server to tell
Firefox it's OK to use the font. On my web server I edited my apache configuration (/etc/apache2/apache2.conf in my case), adding the following lines:
AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf
<FilesMatch "\.(ttf|otf|eot)$">
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>
</FilesMatch>
The AddType directive adds the appropriate MIME types to the HTTP response. The <FilesMatch> directive applies the directives it encloses only to files with extensions .ttf, .otf, and .eot. The <IfModule> directive checks to see that the Apache headers module is loaded. And finally when those conditions are met, we set the Access-Control-Allow-Origin header to *. You can also put these directives into a .htaccess file.

In my case there was one other thing I needed to do on the server. I didn't have the "headers" module loaded in Apache, so I added it and restarted:
sudo a2enmod headers
sudo /etc/init.d/apache2 restart
After that the font started rendering in Firefox, even though it is coming from a different domain. If you are still having problems, note that you can view the HTTP headers returned from the server using the Net panel of Firebug. Here's a screen-shot of my Firebug net panel. The changes to the response header are highlighted:

33 comments:

Forrest said...

Great, but this gives everyone access to the font. If you want to pick and choose which domains have access, this method here works well http://www.lowest-common-denominator.com/2010/01/http_access_control_to_multipl.php

The Cook said...

Forrest,

Thanks for the pointer and your comment. I had considered putting in a single domain name (www.cssbakery.com) instead of '*'. One way to support a set of domains would be to copy the font to several directories on the server (one per domain) and customize the .htaccess file in each of those directories.

The solution you referenced is nice since it allows you to support a list of domains from a single directory on the server. Thanks again for the link.

mic said...

great post, just found what i was looking for

Jacob Magnusson said...

Thanks Minnie!

My problem was pretty much like yours, but reversed. It works perfectly from my Ubuntu 10.10 server, but not on my OS X dev machine where I'm serving static media with the built in Apache.

Alwaison said...

Lifesaver!! Thank you guys!

PIERO WebDesigner said...

Hi brother. I need your help! =)

My example case:

My Blog is a Blogger platform and using a personal domain via DNS in Blogger settings.
My domain is "http://teste.viploungemodario.com.br/" .

My files of fonts, images, css, js, and others is hosted in sub-domain of my server with CPanel and acess a ".htaccess" file.
My domain for files is "http://blog.viploungemodario.com.br/".
A exact folder / patch for access a font files is "http://blog.viploungemodario.com.br/font/"

I need your help to create a data structure of ".htaccess" file and host in what domain / folder / path?

Save me please!

Thank you.

Best regards, Piero.

PS: I'm from Brasil. My english is very poor.

PIERO WebDesigner said...

Ohhhhh, the best solution!!!

Thank you very much!

I love you, hehehe =)

cssbakery said...

Piero, Thanks! :-)

John said...

Thank you so much...I was banging my head against the wall for an hour before I came across this helpful article. I implemented the script and BOOM...instant happiness. The weird thing was the font was displaying properly in every browser but FF from locally hosted files.

Anyway, thanks again!!!!!!!

gamep01nt said...

I still dont't understand, my blog uses @font-face and it doesnt load in firefox..Maybe because the font is from https://sites.google.........and not from my blog, i'm just a typical blogspot blogger and not having my own hosting. How do i fix this?

CSSBakery said...

gamep01nt, I'd be surprised if Google isn't setting the Access-Control-Allow-Orig header correctly. If you post a comment here with the @font-face code you are using I'll take a look to see what's going on. You can also check it yourself if you install Firebug, open the Net tab, load your site. The Net tab will show all files downloaded. Find the font file in the list, click the plus sign and examine the response headers.

gamep01nt said...

thnx for the reply admin, it seems that i found my solution, i use typekit. no need to worry about this anymore. but then again, thanks!

monstress said...

I was having the same problem and added this to my styles using the fonts placed by @fontface: font-family: 'AWConquerorSansLight';
-webkit-font-smoothing: antialiased;
font-weight:normal;}

Anonymous said...

You can also make an dynamic css-file which is headered by php. That also solves the problem!

Matt Costain said...

Thanks for that. Super helpful.

DC said...

If you don't have access to the config files, following .htaccess edit works well: http://stackoverflow.com/questions/2892691/font-face-fonts-only-work-on-their-own-domain

DC said...

N/M, the .htaccess fix I linked to above works fine for Firefox on PC, but for some reason it's still breaking down for Firefox on Mac...

html5 converter said...

Thanks for sharing your info. I really appreciate your efforts and I will be waiting for your further write ups thanks once again.

Fred said...

Works perfectly, very grateful I found your post before I spent hours on this (which is what I normally do...)

nMasK said...

Thanks, it works! :)

Anonymous said...

u the man

nioc said...

You can make it with a script too and tha meta-tag BASE.
Here in smarty :


Or maybe in js.

CSSBakery said...

Nioc, Thank you for the comment

MajedDH said...

i've tried this but no solution , can u help me?

CSSBakery said...

MajedDH, Did you change your Apache configuration and what does Firebug show?

Anonymous said...

Perfect!

hemcoined said...

The weird thing was the font was displaying properly in every browser but FF from locally hosted files.
Load Systems

Anant said...

how to do the same in windows OS

CSSBakery said...

Anant, I assume you mean for Windows IIS server rather than Apache. I don't use it so I'm not sure. This post on Stackoverflow might help you: http://stackoverflow.com/questions/12458444/enabling-cross-origin-resource-sharing-on-iis7

Good luck.

Rajni Kakadiya said...

Here is solution: http://stackoverflow.com/questions/2856502/css-font-face-not-working-with-firefox-but-working-with-chrome-and-ie

Anonymous said...

Hello
I have a same problem.
Actually, I am loading css from rackspace CDN to my website.
at that time this is not working but when I am loading css from local server , it works fine.

Bt when css including from rackspace cdn then it is creating issue same issue.

I added following code in my htaccess file



Header set Access-Control-Allow-Origin "*"



Where should I put following lines.
AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf

Please help me.

Thanks

CSSBakery said...

I don't use the Racksapce CDN so not sure how much I can help. It looks like you need to use the Rackspace Cloud API to setup CORS Headers on your container. See this post on Stackoverflow, which references the CORS documentation on Rackspace.
Good luck.

Hardy Hélène said...

Hi, your post seams really interesting but I don't know what you mean by "On my web server I edited my apache configuration (/etc/apache2/apache2.conf in my case)" how do you do reach that? (it might sound stupid)
is it on my my web hosting (OVH for instance) ? thanks in advance :)

Post a Comment