Bypassing the Same-Origin-Policy For Local Files During Development
downloadable font: download failed …: status=2147500037
Are you ever stumbled accross weired errors with font-files, that could not be loaded, or SVG-graphics, that are not shown during local development on your machine using
file:///-URI’s, though everything works as expected, if you push the content to a webserver and access it via HTTP?
Furthermore, the browsers behave very differently here.
Firefox, for example, just states, that the download of the font failed:
downloadable font: download failed (font-family: "XYZ" style:normal weight:normal stretch:normal src index:0): status=2147500037 source: file:///home/you/path/to/font/xyz.woff
Meanwhile, Chrome just happily uses the same font. Considering the SVG-graphics, that are not shown, Firefox just does not show them, like it would not be able to at all. Chrome logs an error:
Unsafe attempt to load URL file:///home/you/path/to/project/img/sprite.svg#logo from frame with URL file:///home/you/path/to/project/templates/layout.html. Domains, protocols and ports must match
…though, no protocol, domain or port is involved.
The Same-Origin Policy
The reason for this strange behavior is the Same-origin policy. Chrome gives you a hint in this direction with the remark that something does not match. I found the trail, that lead me to this explanation, while googling for the strange error message, that Firefox gives for the fonts, that can not be loaded.
The Same-origin policy forbids, that locally stored files can access any data, that is stored in a parent-directory. They only have access to files, that reside in the same directory or in a directory beneath it.
You can read more about that rule on MDN.
I often violate that rule, when developing templates for dynamically rendered pages with Thymeleaf, or similar techniques.
That is, because I like to place the template-files on a subdirectory of the directory, that contains my webapp (
src/main/webapp with Maven):
I packed a simple example-project for developing static templates with LESS, nodejs and grunt, that shows the problem and the quick solution for Firefox presented later. You can browse it on my juplo.de/gitweb, or clone it with:
git clone http://juplo.de/git/examples/template-development
Cross-Browser SolutionUnfortunately, there is no simple cross-browser solution, if you want to access your files through
file:///-URI’s during development.
The only real solution is, to access your files through the HTTP-protocol, like in production.
If you do not want to do that, the only two cross-browser solutions are, to
- turn of the Same-origin policy for local files in all browsers, or
- rearrange your files in such a way, that they do not violate the Same-origin policy (as a rule, all resources linked in a HTML-file must reside in the same directory as the file, or beneath it).
The only real cross-browser solution is to circumvent the problem altogether and serve the content with a local webserver, so that you can access it through HTTP, like in production. You can read how to extend the example-project mentioned above to achieve that goal in a follow up article.
Turn Of Security
Turning of the Same-origin policy is not recommended. I would only do that, if you only use your browser, to access the HTML-files under development ‐ which I doubt, that it is the case. Anyway, this is a good quick test to validate, that the Same-origin policy is the source of your problems ‐ if you quickly re-enable it after the validation.
falseon the about:config-page.
Restart Chrome with
--allow-file-access-from-files(for more, see this question on Stackoverflow).
Quick Fix For Firefox
If you develop with Firefox, there is a quick fix, to bypass the Same-origin policy for local files.
As the explanation on MDM stats, a file loaded in a frame shares the same origin as the file, that contains the frameset. This can be used to bypass the policy, if you place a file with a frameset in the topmost directory of your development-folder and load the template under development through that file.
In my case, the frameset-file looks like this:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Frameset to Bypass Same-Origin-Policy