Firefox Is The New Enemy
When I first started designing websites there was one enemy. Internet
Explorer. No matter what you did it did not work. Sites were designed
for “Firefox 0.7 ++” or just did look horrible. Well they did work but only
as plain/text document. Internet Explorer lost a serious amount of
market share, the new versions became more and more standard compliant
and you had less work creating stunning sites that work on all browsers.
Most people learned to use Firefox or another alternative the last few
years. Even if it is not as necessary as it was. But today I ran into
something only Firefox screws up. Cross-Origin Resource Sharing.
Explaining The Setup
Sounds complicated, doesn’t it? Well let me give you an easy example
why I ran into this problem. I deployed some Django sites today and
they share the same static files. Let us assume we have three domains.
They all represent one Django project and are all hosted on the same
server. Since I do not care about the flavor of the month I used
lighttpd as webserver. Do not start giving me all the reasons to
use nginx. I know them and I still decided to stay with lighttpd. All
Django projects run as wgsi on a different port using gunicorn.
So what you basically do is set the document root of your webserver to
the static directory that contains all the files and create three
conditions, for every domain, to tell lighttpd to proxy requests to the
corresponding project. I will talk about this setup in another post.
Accessing Your Static Files
Now you tell your Django projects that they should access the static
http://$ip/. Everything looked fine till I did the
last check on my Windows box with Firefox and Internet Explorer.
I have some fonts embedded in my stylesheets. font-face works fine if
you remember to convert your fonts in a format Internet Explorer
understands. But Firefox showed the fallback font. What happend?
Firefox refuses to load files that are not on the same domain as your
website. Loading something form
$ip when you opened
does not work. I am currently not sure what they try to achieve with
this behaviour but I am sure that there are some good reasons.
Good Reasons For Everything
When I talk about good reasons and Firefox in one sentence you should
read it in the most sarcastic voice you can imagine. There is a reason
why I call Firefox useless these days. Of course it did something
great in the past. Thanks to Firefox we had a tiny, fast browser that
was a perfectly fine alternative to Internet Explorer and Mozilla.
After the 1.0 release everything went downhill. Firefox became bigger
and slower. At some point they decided that releasing one major release
every week is the best idea since sliced bread and that those stupid
users are the best beta testers you can get.
It could be possible that I am a bit exaggerating but you get the idea
and I think you can understand why I declare Firefox the new Internet
Solving This Problem
There is an easy way to solve it. You just have to tell Firefox that
it is okay to access those files. Add
to your response header and everything is fine.
The worst solution I know is patching this with your application. There
are better options. Use your webserver.
mod_setenv and add the following line to your configuration.
setenv.add-response-header = ( “Access-Control-Allow-Origin” => “*” )
This allows every domain to load stuff from your server. You could replace
the wildcard with domain names to restrict access.
If you are on another server just search in your documentation how to
add a response header and you are fine. Quick examples, without modules
or anything else.
Header set Access-Control-Allow-Origin “*”
add name=”Access-Control-Allow-Origin” value=”*”
add_header Access-Control-Allow-Origin *
I strongly suggest you do not use the wildcard. Every domain can load your
files. If you are planning to run a CDN this could be viable, for everything
else think about what you are doing.
If you are not using subdomains in your Django installation you can also
create a subdomain. But this would not work for my current setup since
all subdomains have to be processed by Django.
I do not know another browser beside Firefox that implements CORS. But it
could become a standard. There could be some reasons why they implemented
this “feature”. Being prepared when something from another domain does not
load one day, after a browser update, is a good idea.