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.
XMLHttpRequest cannot load http://localhost/api/v1/products?_=1355583847077.
Origin null is not allowed by Access-Control-Allow-Origin.
Error: error
$.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);
})
_ 1355583610778
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
Nothing here...
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
I solved it in a very easy way, by adding the following header to my server code (php):
header('Access-Control-Allow-Origin: *');
Yep, this is definately a cross-domain issue. But don't fret, there's two solutions to this problem.
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.
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.
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 :)
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", "*");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With