Monday, 17 June 2013

Chrome issue - XMLHttpRequest cannot load file: Cross origin requests are only supported for HTTP

Lately I have been developing a very silly webpage with bare HTML and Javascript. I'm not very familiar with websites and web in general, so I just write some code and try it out through a browser, with no HTTP server running.
Everything was working just fine until I decided to use external XML files to get input from; this is the code snippet I used to get XML input (thanks W3schools.com):
...
if (window.XMLHttpRequest) {
   xhttp = new XMLHttpRequest(); // for IE7+, Firefox, Chrome, Opera, Safari
} else {
   xhttp = new ActiveXObject("Microsoft.XMLHTTP"); // for IE6, IE5
}
xhttp.open("GET", "samplexml/externalfile.xml", false);
xhttp.send();
xmlDoc = xhttp.responseXML;
xmlChildren = xmlTree.documentElement.childNodes;
xmlChildren[0].nodeName; // prints the tag of the first node
...
where samplexml/externalfile.xml is the relative path to the XML file.
If you test this code (again, without any HTTP server!) on a browser like Firefox there won't be any problem: the XML file gets loaded as a charm. The problem is when you try to make it work with Chrome. The console will display a message like the following:
XMLHttpRequest cannot load file:///path/to/project/folder/samplexml/externalfile.xml. Cross origin requests are only supported for HTTP.
Basically the problem is that Chrome has strict permissions for reading files out of the local file system. The best thing to do is to use a simple HTTP server, as suggested here.
This could sound like a lot of stuff and a lot of steps to so, as well as a lot of bad words to shout throughout several days trying to make things work properly. Actually this is not the case: Python comes in handy with its SimpleHTTPServer class, a simple HTTP server which provides standard GET and HEAD request handlers; the cool thing is that it's actually super easy to set up a HTTP server with this class.
[lillo@pc-lillo ~]$ cd /path/to/project/folder
[lillo@pc-lillo project]$ python -m SimpleHTTPServer 8888
Serving HTTP on 0.0.0.0 port 8888 ...
where project is your project folder. Now just open the application from Chrome (localhost):
http://localhost:8888
That's it; now Chrome will not complain anymore, and you're free to read as many XML files as you wish. When you're done just Ctrl-C to exit Python.
Sweet.