Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access-Control-Allow-Origin - localhost

I have problems with receiving json through ajax, the error is below. According to the information I've found so far regarding the error this seems to be some kind of cross domain issue, but I have no idea of what that means and how to solve it.

There may be an issue with the response header (I have created the API myself and have no experiences since before), however a 200 OK is received if accessing the url directly in the browser.

If accessing the url directly in the browser valid json is shown, so that shouldn't be the problem.

How can this be solved?

Note: The url goes to an Apache server, not a file that has been the case for 95% of the questions here on Stack that I've read about the issue.

Error in inspector:

XMLHttpRequest cannot load http://localhost/api/v1/products?_=1355583847077.
Origin null is not allowed by Access-Control-Allow-Origin.
Error: error 

The code:

    $.ajaxSetup ({
      url: "http://localhost/api/v1/products", // <--- returns valid json if accessed in the browser
      type: "GET",
      dataType: "json",
      cache: false,
      contentType: "application/json"
    })
    $.ajax({
        success: function(data){

            console.log("You made it!");
        },
        error: function(xhr) {
           console.log("Error: " + xhr.statusText);
       }
    }).done(function(data){
        console.log(data);
    })

Params

_ 1355583610778

Headers

Response Headers:

Connection  Keep-Alive
Content-Length  3887
Content-Type    application/json
Date    Sat, 15 Dec 2012 14:50:53 GMT
Keep-Alive  timeout=5, max=100
Server  Apache/2.2.14 (Unix) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l PHP/5.3.1 mod_perl/2.0.4 Perl/v5.10.1
X-Powered-By    PHP/5.3.1

Request Headers:

Accept  application/json, text/javascript, */*; q=0.01
Accept-Encoding gzip, deflate
Accept-Language sv-SE,sv;q=0.8,en-US;q=0.5,en;q=0.3
Connection  keep-alive
Host    localhost
Origin  null
User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:17.0) Gecko/17.0 Firefox/17.0

Response

Nothing here...

like image 791
holyredbeard Avatar asked Dec 15 '12 15:12

holyredbeard


5 Answers

More PHP header settings

header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type');

Good Luck

like image 62
Thabelo Phusu Mmbengeni Avatar answered Sep 25 '22 04:09

Thabelo Phusu Mmbengeni


I solved it in a very easy way, by adding the following header to my server code (php):

header('Access-Control-Allow-Origin: *');
like image 36
holyredbeard Avatar answered Oct 23 '22 19:10

holyredbeard


Yep, this is definately a cross-domain issue. But don't fret, there's two solutions to this problem.

Using JSONP

You can implement support for JSONP (JSON with padding) on the server (i.e. Fergus Morrow's solution). JSONP works cross-domain out-of-the-box and is basically JSON padded with a function call.

In your .ajaxSetup set dataType to jsonp and then on the server-side you should make sure to check for an url parameter named callback in the request. If that parameter is set, the JSON response has to be padded accordingly.

parseThis({ "json": "can", "be": "put", "in": "here" });

The above assumes callback is set to parseThis. jQuery will per default generate a function name, but you can override this by setting the value of jsonpCallback in your .ajaxSetup.

You can also use a shortcut to tell jQuery that you are requesting JSONP by just adding ?callback=? to the request url.

Using Access-Control-Allow-Origin

An alternate solution is to set the Access-Control-Allow-Origin header in your response.

Access-Control-Allow-Origin: *

The above will allow any resource to use the service cross-domain. Read up on the article linked below for more information on how to configure Access-Control-Allow.


If you want to know more on Access-Control-Origin and CORS I recommend this article on MDN.

like image 20
mekwall Avatar answered Oct 23 '22 18:10

mekwall


Try and implement some form of JSONP mechanism. If you're using PHP it could be something as simple as this...

/* If a callback has been supplied then prepare to parse the callback
 ** function call back to browser along with JSON. */
$jsonp = false;
if ( isset( $_GET[ 'callback' ] ) ) {
    $_GET[ 'callback' ] = strip_tags( $_GET[ 'callback' ] );
    $jsonp              = true;

    $pre  = $_GET[ 'callback' ] . '(';
    $post = ');';
} //isset( $_GET[ 'callback' ] )

/* Encode JSON, and if jsonp is true, then ouput with the callback
 ** function; if not - just output JSON. */
$json = json_encode( /* data here */ );
print( ( $jsonp ) ? $pre . $json . $post : $json );

All this would do is check for a $_GET var called callback, and then wrap the output in a function call - taking the $_GET['callback'] name as a function name.

Then your AJAX call becomes something like this...

$.ajax({
  type: 'GET',
  url: '/* script here */ ', 
  data: /* data here - if any */,
  contentType: "jsonp", // Pay attention to the dataType/contentType
  dataType: 'jsonp', // Pay attention to the dataType/contentType
  success: function (json) {
    /* call back */
  }
});

When jQuery is given 'jsonp' as a dataType/contentType it will take care of providing a callback function name for you - and setting the callback function up etc; meaning you don't have to do anything really!

From the jQuery documentation:

"jsonp": Loads in a JSON block using JSONP. Adds an extra "?callback=?" to the end of your URL to specify the callback. Disables caching by appending a query string parameter, "_=[TIMESTAMP]", to the URL unless the cache option is set to true.

Source

In closing; JSONP is going to be your best bet - I've included PHP code in the off chance that your server side script is using PHP; if not then the principles are the same. The jQuery/client side stuff stays the same regardless of server side technologies though. (in general)

Good luck :)

like image 7
Fergus In London Avatar answered Oct 23 '22 17:10

Fergus In London


If it's an ASP.NET WEB application then you can also put this in your Global.aspx:

HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

like image 3
Vasile Laur Avatar answered Oct 23 '22 17:10

Vasile Laur