“Origin null is not allowed by Access-Control-Allow-Origin” error for request made by application running from a file:// URL
Asked Answered
N

17

596

I'm developing a page that pulls images from Flickr and Panoramio via jQuery's AJAX support.

The Flickr side is working fine, but when I try to $.get(url, callback) from Panoramio, I see an error in Chrome's console:

XMLHttpRequest cannot load http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150. Origin null is not allowed by Access-Control-Allow-Origin.

If I query that URL from a browser directly it works fine. What is going on, and can I get around this? Am I composing my query incorrectly, or is this something that Panoramio does to hinder what I'm trying to do?

Google didn't turn up any useful matches on the error message.

EDIT

Here's some sample code that shows the problem:

$().ready(function () {
  var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150';

  $.get(url, function (jsonp) {
    var processImages = function (data) {
      alert('ok');
    };

    eval(jsonp);
  });
});

You can run the example online.

EDIT 2

Thanks to Darin for his help with this. THE ABOVE CODE IS WRONG. Use this instead:

$().ready(function () {
  var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&minx=-30&miny=0&maxx=0&maxy=150&callback=?';

  $.get(url, function (data) {
    // can use 'data' in here...
  });
});
Numbskull answered 29/8, 2010 at 16:12 Comment(7)
What does the URL look like that you are making the request from? This doesn't happen to be a dynamically generated iframe that you document.write into, for example?Rives
Can you post the HTTP response from request to each service. I bet Panoramio isn't serving up Access-Control-Allow-Origin. See w3.org/TR/cors for examples.Domela
@Kevin, you don't need those headers if the server sends JSONP.Novelette
@Pekka, I'm running the page from my local machine at the moment (file:///C:/). No iframe is involved.Numbskull
@drew what happens if you run it from a http URL? It shouldn't make a difference this way around, but just to exclude the possibility.Rives
@Pekka, I ran it from jsFiddle and had the same issue (link in the updated question!)Numbskull
There is jsonp.jit.su it's a free JSON Proxy "Enables cross-domain requests to any JSON API." And it's on Github github.com/afeld/jsonpKoss
Q
441

For the record, as far as I can tell, you had two problems:

  1. You weren't passing a "jsonp" type specifier to your $.get, so it was using an ordinary XMLHttpRequest. However, your browser supported CORS (Cross-Origin Resource Sharing) to allow cross-domain XMLHttpRequest if the server OKed it. That's where the Access-Control-Allow-Origin header came in.

  2. I believe you mentioned you were running it from a file:// URL. There are two ways for CORS headers to signal that a cross-domain XHR is OK. One is to send Access-Control-Allow-Origin: * (which, if you were reaching Flickr via $.get, they must have been doing) while the other was to echo back the contents of the Origin header. However, file:// URLs produce a null Origin which can't be authorized via echo-back.

The first was solved in a roundabout way by Darin's suggestion to use $.getJSON. It does a little magic to change the request type from its default of "json" to "jsonp" if it sees the substring callback=? in the URL.

That solved the second by no longer trying to perform a CORS request from a file:// URL.

To clarify for other people, here are the simple troubleshooting instructions:

  1. If you're trying to use JSONP, make sure one of the following is the case:
    • You're using $.get and set dataType to jsonp.
    • You're using $.getJSON and included callback=? in the URL.
  2. If you're trying to do a cross-domain XMLHttpRequest via CORS...
    1. Make sure you're testing via http://. Scripts running via file:// have limited support for CORS.
    2. Make sure the browser actually supports CORS. (Opera and Internet Explorer are late to the party)
Questionnaire answered 19/9, 2010 at 6:6 Comment(4)
So what is the solution to this?Budgie
Some browsers like chrome allow CORS if started with the parameter --allow-file-access-from-filesParsley
callback=? didn't work for me, But jsonp=? did. Any explanation for that?Inevasible
@crunkchitis: I'm not sure why callback=? isn't working for you, given that the current jQuery docs still say it should but, if I'm reading them correctly, they also say that anything_else=? will also work.Questionnaire
F
78

You need to maybe add a HEADER in your called script, here is what I had to do in PHP:

header('Access-Control-Allow-Origin: *');
Foliaceous answered 11/2, 2011 at 10:59 Comment(1)
It looks like your link is dead.Dicarlo
I
77

For a simple HTML project:

Python 2
cd project
python -m SimpleHTTPServer 8000
Python 3
cd project
python -m http.server 8000

Then browse your file.

Ignace answered 7/3, 2012 at 15:49 Comment(0)
N
22

Works for me on Google Chrome v5.0.375.127 (I get the alert):

$.get('http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=?&minx=-30&miny=0&maxx=0&maxy=150',
function(json) {
    alert(json.photos[1].photoUrl);
});

Also I would recommend you using the $.getJSON() method instead as the previous doesn't work on IE8 (at least on my machine):

$.getJSON('http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=?&minx=-30&miny=0&maxx=0&maxy=150', 
function(json) {
    alert(json.photos[1].photoUrl);
});

You may try it online from here.


UPDATE:

Now that you have shown your code I can see the problem with it. You are having both an anonymous function and inline function but both will be called processImages. That's how jQuery's JSONP support works. Notice how I am defining the callback=? so that you can use an anonymous function. You may read more about it in the documentation.

Another remark is that you shouldn't call eval. The parameter passed to your anonymous function will already be parsed into JSON by jQuery.

Novelette answered 29/8, 2010 at 16:14 Comment(1)
i get Uncaught TypeError: $.get is not a function at <anonymous>:1:3Ecospecies
S
9

As long as the requested server supports the JSON data format, use the JSONP (JSON Padding) interface. It allows you to make external domain requests without proxy servers or fancy header stuff.

Solomon answered 6/5, 2011 at 16:27 Comment(0)
M
7

If you are doing local testing or calling the file from something like file:// then you need to disable browser security.

On MAC: open -a Google\ Chrome --args --disable-web-security

Mascagni answered 20/8, 2013 at 18:35 Comment(0)
L
6

It's the same origin policy, you have to use a JSON-P interface or a proxy running on the same host.

Leix answered 29/8, 2010 at 16:15 Comment(0)
S
5

We managed it via the http.conf file (edited and then restarted the HTTP service):

<Directory "/home/the directory_where_your_serverside_pages_is">
    Header set Access-Control-Allow-Origin "*"
    AllowOverride all
    Order allow,deny
    Allow from all
</Directory>

In the Header set Access-Control-Allow-Origin "*", you can put a precise URL.

Starnes answered 29/7, 2011 at 18:58 Comment(3)
this does not work on XAMPP's Apache. the problem still exists.Hickory
This is unsafe. See here why; #7565332Avifauna
It's unsafe as @RobQuist said.Schnorkle
B
4

In my case, same code worked fine on Firefox, but not on Google Chrome. Google Chrome's JavaScript console said:

XMLHttpRequest cannot load http://www.xyz.com/getZipInfo.php?zip=11234. 
Origin http://xyz.com is not allowed by Access-Control-Allow-Origin.
Refused to get unsafe header "X-JSON"

I had to drop the www part of the Ajax URL for it to match correctly with the origin URL and it worked fine then.

Burrow answered 3/1, 2012 at 19:9 Comment(0)
O
2

As final note the Mozilla documentation explicitly says that

The above example would fail if the header was wildcarded as: Access-Control-Allow-Origin: *. Since the Access-Control-Allow-Origin explicitly mentions http://foo.example, the credential-cognizant content is returned to the invoking web content.

As consequence is a not simply a bad practice to use '*'. Simply does not work :)

Openandshut answered 16/8, 2013 at 9:11 Comment(0)
S
2

Not all servers support jsonp. It requires the server to set the callback function in it's results. I use this to get json responses from sites that return pure json but don't support jsonp:

function AjaxFeed(){

    return $.ajax({
        url:            'http://somesite.com/somejsonfile.php',
        data:           {something: true},
        dataType:       'jsonp',

        /* Very important */
        contentType:    'application/json',
    });
}

function GetData() {
    AjaxFeed()

    /* Everything worked okay. Hooray */
    .done(function(data){
        return data;
    })

    /* Okay jQuery is stupid manually fix things */
    .fail(function(jqXHR) {

        /* Build HTML and update */
        var data = jQuery.parseJSON(jqXHR.responseText);

        return data;
    });
}
Sagitta answered 19/10, 2013 at 13:32 Comment(0)
I
1

I use Apache server, so I've used mod_proxy module. Enable modules:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Then add:

ProxyPass /your-proxy-url/ http://service-url:serviceport/

Finally, pass proxy-url to your script.

Iroquoian answered 2/4, 2012 at 11:52 Comment(0)
P
1

For PHP - this Work for me on Chrome, safari and firefox

https://w3c.github.io/webappsec-cors-for-developers/#avoid-returning-access-control-allow-origin-null

header('Access-Control-Allow-Origin: null');

using axios call php live services with file://

Pinette answered 6/8, 2019 at 15:14 Comment(1)
This also works form me, Notice how null is a STRING and not actual NULL. I use it asheader('Access-Control-Allow-Origin: '.( trim($_SERVER['HTTP_REFERER'],'/') ?:'null'),true); that allow cross origin from a remote server to another as well and fall to to (string) null for local file.Gyrfalcon
R
0

There is a small problem in the solution posted by CodeGroover above , where if you change a file, you'll have to restart the server to actually use the updated file (at least, in my case).

So searching a bit, I found this one To use:

sudo npm -g install simple-http-server # to install
nserver # to use

And then it will serve at http://localhost:8000.

Rottenstone answered 6/6, 2013 at 23:15 Comment(0)
A
0

I also got the same error in Chrome (I didn't test other browers). It was due to the fact that I was navigating on domain.com instead of www.domain.com. A bit strange, but I could solve the problem by adding the following lines to .htaccess. It redirects domain.com to www.domain.com and the problem was solved. I am a lazy web visitor so I almost never type the www but apparently in some cases it is required.

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [R=301,L]
Abroach answered 30/9, 2013 at 7:47 Comment(0)
B
0

Make sure you are using the latest version of JQuery. We were facing this error for JQuery 1.10.2 and the error got resolved after using JQuery 1.11.1

Borrego answered 10/7, 2014 at 6:32 Comment(0)
F
0

Folks,

I ran into a similar issue. But using Fiddler, I was able to get at the issue. The problem is that the client URL that is configured in the CORS implementation on the Web API side must not have a trailing forward-slash. After submitting your request via Google Chrome and inspect the TextView tab of the Headers section of Fiddler, the error message states something like this:

*"The specified policy origin your_client_url:/' is invalid. It cannot end with a forward slash."

This is real quirky because it worked without any issues on Internet Explorer, but gave me a headache when testing using Google Chrome.

I removed the forward-slash in the CORS code and recompiled the Web API, and now the API is accessible via Chrome and Internet Explorer without any issues. Please give this a shot.

Thanks, Andy

Footpath answered 21/8, 2014 at 5:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.