nginx + @font-face + Firefox / IE9

Hello,

Just transferred my site from site5's shared hosting to Linode, so please don't be harsh if I missed something evident ^^

I've got my WordPress site running pretty well on ngnix & MaxCDN, but my @font-face fonts (served from cdn.domain.com) stopped working in IE9 and FF (@font-face failed cross-origin request. Resource access is restricted.)

I've googled for a hours and tried adding all of the following to my config files:

location ~* ^.+\.(eot|otf|ttf|woff)$ {
    add_header Access-Control-Allow-Origin *;
}
location ^/fonts/ {
    add_header Access-Control-Allow-Origin *;
}
location / {
    if ($request_filename ~* ^.*?/([^/]*?)$)
    {
        set $filename $1;
    }

    if ($filename ~* ^.*?\.(eot)|(otf)|(ttf)|(woff)$){
        add_header 'Access-Control-Allow-Origin' '*'; 
    }
}

With all of the following combinations:

add_header Access-Control-Allow-Origin *;
add_header 'Access-Control-Allow-Origin' *;
add_header Access-Control-Allow-Origin '*';
add_header 'Access-Control-Allow-Origin' '*';

Of course, I've restarted nginx after every change.

The headers just don't get sent at all no matter what I do :(

I have the default Ubuntu apt-get build nginx which should include the headers module by default… How do I check what modules are installed, or what else could be causing this error?

Thanks,

Philip

15 Replies

You mentioned WordPress… are you using fastcgi? If so, "add_header Access-Control-Allow-Origin *;" outside of any location block should definitely do it, I figure. Anything that relies on adding the header to a request for a font won't do anything, since you aren't going to get requests for the fonts any more.

You are verifying the existence of the header when testing (curl -i http://example.com/) and not just testing the effects, right?

Yes, I'm using fastcgi.

I'm looking at headers in the Chrome's Network panel…

If I use

add_header Access-Control-Allow-Origin *;

instead of

location ~* ^.+\.(eot|otf|ttf|woff)$ { 
    add_header Access-Control-Allow-Origin *; 
}

(i.e. I'm adding the header to everything and not just the fonts) and do:

curl -i http://cdn.lingualift.com/

It does return "Access-Control-Allow-Origin: *" but that isn't so when I look at a font's headers in Chrome, and the fonts still don't work in FF & IE9.

OK, I just tried to do "curl -I" on a font and it did return Access-Control-Allow-Origin: *, yet the header is still not visible in Chrome's Network panel, and FF & IE9 still don't display the font (CSS3117: @font-face failed cross-origin request. Resource access is restricted.)

Any ideas what could be the cause of this?

Silly question but have you cleared your browser cache?

Can you post a link to the page you're having problems with I'll see if it works here.

http://japanese.lingualift.com/

I'm not getting the header on any part of the site be it html/css or font using curl.

nginx add header works in the server block so just under where you have````
server_name japanese.lingualift.com;

Add

add_header Access-Control-Allow-Origin: *;
````
Then restart nginx.

Done…

When I do:

curl -I http://cdn.lingualift.com/wp-content/themes/no/fonts/oksanatextnarrow-bold-webfont.eot

I do receive:

Access-Control-Allow-Origin: *

(among other things)

But not in the browsers :(

I don't

$ curl -I http://cdn.lingualift.com/wp-content/themes/no/fonts/oksanatextnarrow-bold-webfont.eot
HTTP/1.1 200 OK
Server: nginx/0.8.36
Date: Thu, 17 Nov 2011 21:16:09 GMT
Content-Type: application/octet-stream
Connection: keep-alive
Content-Length: 25419
Last-Modified: Tue, 15 Nov 2011 18:10:33 GMT
Expires: Fri, 16 Nov 2012 17:50:58 GMT
Cache-Control: max-age=31536000
Pragma: public
X-Powered-By: W3 Total Cache/0.9.2.4
CF-Cache-Status: HIT
Vary: Accept-Encoding
X-Cache: HIT
Accept-Ranges: bytes

However the CF-Cache-Status: HIT indicates this is from cloud flare maybe that's you're problem cloud flare aren't forwarding the header?

hm, very strange…

First of all, I also stopped receiving the access header through curl…

Also, I've disabled CloudFlare completely, yet I still keep getting CF-Cache-Status: HIT among the headers.

OK, upon reading the spec, it looks like my idea of it was backwards; I was assuming it was something where the main site would have to add the header, rather than something that would have to be on the embedded content itself.

So yes, you'll want to probably only put the header on the font files.

Here's what I'm seeing from here… it's not showing up when I go to the "real" URL for the file, and neither are the CF-Cache-Status or X-Cache headers, so I suspect it is indeed not being sent.

rtucker@witte:~$ curl -I http://cdn.lingualift.com/wp-content/themes/no/fonts/oksanatextnarrow-bold-webfont.eot
HTTP/1.1 200 OK
Server: nginx/0.8.36
Date: Thu, 17 Nov 2011 22:10:36 GMT
Content-Type: application/octet-stream
Connection: keep-alive
Content-Length: 25419
Last-Modified: Tue, 15 Nov 2011 18:10:33 GMT
Expires: Fri, 16 Nov 2012 22:10:36 GMT
Cache-Control: max-age=31536000
Pragma: public
X-Powered-By: W3 Total Cache/0.9.2.4
Accept-Ranges: bytes
CF-Cache-Status: MISS
Vary: Accept-Encoding
X-Cache: MISS

rtucker@witte:~$ curl -I http://japanese.lingualift.com/wp-content/themes/no/fonts/oksanatextnarrow-bold-webfont.eot
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 17 Nov 2011 22:11:24 GMT
Content-Type: application/octet-stream
Content-Length: 25419
Last-Modified: Tue, 15 Nov 2011 18:10:33 GMT
Connection: keep-alive
Expires: Fri, 16 Nov 2012 22:11:24 GMT
Cache-Control: max-age=31536000
Pragma: public
Cache-Control: max-age=31536000, public, must-revalidate, proxy-revalidate
X-Powered-By: W3 Total Cache/0.9.2.4
Accept-Ranges: bytes

rtucker@witte:~$ curl -I http://japanese.lingualift.com/
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 17 Nov 2011 22:11:53 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Vary: Accept-Encoding
X-Pingback: http://japanese.lingualift.com/xmlrpc.php
X-Powered-By: W3 Total Cache/0.9.2.4
Access-Control-Allow-Origin: *

So, from the X-Powered-By, I have the feeling the font file is coming out of WordPress and is not merely being served as a static file… other stuff coming out of WordPress is fine, though.

So time to do some walking:

rtucker@witte:~$ curl -I http://japanese.lingualift.com/wp-content/
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 17 Nov 2011 22:16:03 GMT
Content-Type: text/html
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.3.8
Access-Control-Allow-Origin: *

rtucker@witte:~$ curl -I http://japanese.lingualift.com/wp-content/themes/
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 17 Nov 2011 22:17:24 GMT
Content-Type: text/html
Connection: keep-alive
Vary: Accept-Encoding
X-Powered-By: PHP/5.3.8
Access-Control-Allow-Origin: *

rtucker@witte:~$ curl -I http://japanese.lingualift.com/wp-content/themes/no/
HTTP/1.1 500 Internal Server Error
Server: nginx
Date: Thu, 17 Nov 2011 22:17:36 GMT
Content-Type: text/html
Connection: keep-alive
X-Powered-By: PHP/5.3.8

rtucker@witte:~$ curl -I http://japanese.lingualift.com/wp-content/themes/no/fonts/
HTTP/1.1 403 Forbidden
Server: nginx
Date: Thu, 17 Nov 2011 22:17:41 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Vary: Accept-Encoding

Something changes between wp-content/themes/ and wp-content/themes/no/.

I've tried running curl again, and I do get the header:

curl -I http://lingualift.com/wp-content/themes/no/fonts/oksanatextnarrow-bolditalic-webfont.ttf
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 17 Nov 2011 23:40:40 GMT
Content-Type: application/x-font-ttf
Content-Length: 54808
Last-Modified: Tue, 15 Nov 2011 18:10:33 GMT
Connection: keep-alive
Expires: Fri, 16 Nov 2012 23:40:40 GMT
Cache-Control: max-age=31536000
Pragma: public
Cache-Control: max-age=31536000, public, must-revalidate, proxy-revalidate
X-Powered-By: W3 Total Cache/0.9.2.4
Access-Control-Allow-Origin: *
Accept-Ranges: bytes

Still don't get it in browsers though…

At this point, I suspect the CDN has the responses cached. Give it another try in about a year.

rtucker@witte:~$ curl -I http://japanese.lingualift.com/wp-content/themes/no/fonts/oksanatextnarrow-bold-webfont.eot
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 18 Nov 2011 00:30:38 GMT
Content-Type: application/octet-stream
Content-Length: 25419
Last-Modified: Tue, 15 Nov 2011 18:10:33 GMT
Connection: keep-alive
Expires: Sat, 17 Nov 2012 00:30:38 GMT
Cache-Control: max-age=31536000
Pragma: public
Cache-Control: max-age=31536000, public, must-revalidate, proxy-revalidate
X-Powered-By: W3 Total Cache/0.9.2.4
Access-Control-Allow-Origin: *
Accept-Ranges: bytes

rtucker@witte:~$ curl -I http://cdn.lingualift.com/wp-content/themes/no/fonts/oksanatextnarrow-bold-webfont.eot
HTTP/1.1 200 OK
Server: nginx/0.8.36
Date: Fri, 18 Nov 2011 00:30:48 GMT
Content-Type: application/octet-stream
Connection: keep-alive
Content-Length: 25419
Last-Modified: Tue, 15 Nov 2011 18:10:33 GMT
Expires: Sat, 17 Nov 2012 00:30:48 GMT
Cache-Control: max-age=31536000
Pragma: public
X-Powered-By: W3 Total Cache/0.9.2.4
CF-Cache-Status: HIT
Vary: Accept-Encoding
Accept-Ranges: bytes
X-Cache: MISS

rtucker@witte:~$ curl -I http://cdn.lingualift.com/wp-content/themes/no/fonts/oksanatextnarrow-bold-webfont.ttf
HTTP/1.1 200 OK
Server: nginx/0.8.36
Date: Fri, 18 Nov 2011 00:32:14 GMT
Content-Type: application/x-font-ttf
Connection: keep-alive
Content-Length: 52480
Last-Modified: Tue, 15 Nov 2011 18:10:33 GMT
Expires: Sat, 17 Nov 2012 00:32:13 GMT
Cache-Control: max-age=31536000
Pragma: public
X-Powered-By: W3 Total Cache/0.9.2.4
Access-Control-Allow-Origin: *
Accept-Ranges: bytes
CF-Cache-Status: MISS
Vary: Accept-Encoding
X-Cache: MISS

Indeed, CDN was probably caching the responses… I've renamed all the font files and they now work as expected :) Thanks for your help!

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct