192
votes

I have made a small xslt file to create an html output called weather.xsl with code as follows:

<!-- DWXMLSource="http://weather.yahooapis.com/forecastrss?w=38325&u=c" -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="yweather"
xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <img src="{/*/*/item/yweather:condition/@text}.jpg"/>
</xsl:template>
</xsl:stylesheet>

I want to load in the html output into a div in an html file which I'm trying to do using jQuery as follows:

<div id="result">
<script type="text/javascript">
$('#result').load('weather.xsl');
</script>
</div>

But I am getting the following error: Origin null is not allowed by Access-Control-Allow-Origin.

I've read about adding a header to the xslt, but I'm not sure how to do that, so any help would be appreciated, and if loading in the html ouput can't be done this way, then advice on how else to do it would be great.

7
Is that your actual load call? There's no path on it at all?T.J. Crowder
To allow local pages/html files (Origin: null) from file system to access external resources(different origins), those external resources should respond with "Access-Control-Allow-Origin": "*" in response header.Maksim Shamihulau

7 Answers

234
votes

Origin null is the local file system, so that suggests that you're loading the HTML page that does the load call via a file:/// URL (e.g., just double-clicking it in a local file browser or similar). Different browsers take different approaches to applying the Same Origin Policy to local files.

My guess is that you're seeing this using Chrome. Chrome's rules for applying the SOP to local files are very tight, it disallows even loading files from the same directory as the document. So does Opera. Some other browsers, such as Firefox, allow limited access to local files. But basically, using ajax with local resources isn't going to work cross-browser.

If you're just testing something locally that you'll really be deploying to the web, rather than use local files, install a simple web server and test via http:// URLs instead. That gives you a much more accurate security picture.

221
votes

Chrome and Safari has a restriction on using ajax with local resources. That's why it's throwing an error like

Origin null is not allowed by Access-Control-Allow-Origin.

Solution: Use firefox or upload your data to a temporary server. If you still want to use Chrome, start it with the below option;

--allow-file-access-from-files

More info how to add the above parameter to your Chrome: Right click the Chrome icon on your task bar, right click the Google Chrome on the pop-up window and click properties and add the above parameter inside the Target textbox under Shortcut tab. It will like as below;

C:\Users\XXX_USER\AppData\Local\Google\Chrome\Application\chrome.exe --allow-file-access-from-files

Hope this will help!

53
votes

Just wanted to add that the "run a webserver" answer seems quite daunting, but if you have python on your system (installed by default at least on MacOS and any Linux distribution) it's as easy as:

python -m http.server  # with python3

or

python -m SimpleHTTPServer  # with python2

So if you have your html file myfile.html in a folder, say mydir, all you have to do is:

cd /path/to/mydir
python -m http.server  # or the python2 alternative above

Then point your browser to:

http://localhost:8000/myfile.html

And you are done! Works on all browsers, without disabling web security, allowing local files, or even restarting the browser with command line options.

2
votes

I would like to humbly add that according to this SO source: https://stackoverflow.com/a/14671362/1743693, this kind of trouble is now partially solved simply by using the following jQuery instruction:

<script> 
    $.support.cors = true;
</script>

I tried it on IE10.0.9200, and it worked immediately (using jquery-1.9.0.js).

On chrome 28.0.1500.95 - this instruction doesn't work (this happens all over as david complains in the comments at the link above)

Running chrome with --allow-file-access-from-files did not work for me (as Maistora's claims above)

2
votes

Adding a bit to use Gokhan's solution for using:

--allow-file-access-from-files

Now you just need to append above text in Target text followed by a space. make sure you close all the instances of chrome browser after adding above property. Now restart chrome by the icon where you added this property. It should work for all.

0
votes

I was looking for an solution to make an XHR request to a server from a local html file and found a solution using Chrome and PHP. (no Jquery)

Javascripts:

var x = new XMLHttpRequest(); 
if(x) x.onreadystatechange=function(){ 
    if (x.readyState === 4 && x.status===200){
        console.log(x.responseText); //Success
    }else{ 
        console.log(x); //Failed
    }
};
x.open(GET, 'http://example.com/', true);
x.withCredentials = true;
x.send();

My Chrome's request header Origin: null

My PHP response header (Note that 'null' is a string). HTTP_REFERER allow cross-origin from a remote server to another.

header('Access-Control-Allow-Origin: '.(trim($_SERVER['HTTP_REFERER'],'/')?:'null'),true);
header('Access-Control-Allow-Credentials:true',true);

I was able to successfully connect to my server. You can disregards the Credentials headers, but this works for me with Apache's AuthType Basic enabled

I tested compatibility with FF and Opera, It works in many cases such as:

From a VM LAN IP (192.168.0.x) back to the VM'S WAN (public) IP:port
From a VM LAN IP back to a remote server domain name.
From a local .HTML file to the VM LAN IP and/or VM WAN IP:port,
From a local .HTML file to a remote server domain name.
And so on.

0
votes

You can load a local Javascript file (in the tree below your file:/ source page) using the source tag:

<script src="my_data.js"></script>

If you encode your input into Javascript, like in this case:

mydata.js:

$xsl_text = "<xsl:stylesheet version="1.0" + ....

(this is easier for json) then you have your 'data' in a Javascript global variable to use as you wish.