Failing to get remote JSON using JSONP - javascript

I'm trying to retrieve a remote JSON using jQuery 1.11.1. The remote server does support jsonp and I'm able to download the .jsonp file by simply entering the call address and ?callback=foo in a browser.
However, when I try to get it using ajax, it fails.
$.ajax({
type: "GET",
url: "http://path-to-remote-server.net/file.jsonp",
dataType: 'jsonp',
jsonp : "callback",
jsonpCallback: "e",
success: function(r) {
console.log(r);
}
});
A quick look at the console tells me that it's a bad request, probably because it seems that jQuery passes a second unwanted parameter, making the request look like this :
http://path-to-remote-server.net/file.jsonp?callback=e&_=1406722474006
This happens even when I omit the jsonp and jsonpCallback options. The request then looks like this :
http://path-to-remote-server.net/file.jsonp?callback=jQuery111106199050471186638_1406722685544&_=1406722685545
Using the short cut $.getJSON doesn't work either, but not for the same reason it seems :
$.getJSON("http://path-to-remote-server.net/file.jsonp?callback=e", function(r){
console.log(r);
});
This doesn't trigger any error in the console, but nothing gets logged either, as if it didn't get anything back from the server.
Why is that, and how can I avoid it?
Thank you all in advance!

From the manual:
cache (default: true, false for dataType 'script' and 'jsonp')
Type: Boolean
If set to false, it will force requested pages not to be cached by the browser. Note: Setting cache to false will only work correctly with HEAD and GET requests. It works by appending "_={timestamp}" to the GET parameters. The parameter is not needed for other types of requests, except in IE8 when a POST is made to a URL that has already been requested by a GET.
So add cache: true to your Ajax parameters.

The last query string argument automatically added by jQuery is needed to avoid browser caching. Otherwise if you do the same JSONP call in the same or in any other page of your site, you will get the cached result instead of the fresh one. So if your server does support JSONP it should accept such requests.
It seems to be a server-side issue, so you should check what is going on there :)

Related

cherrypy/jquery CORS trouble

I've got a simple python web server based on cherrypy. Its resources shall provide an API. THe server has the following code to provide CORS:
def CORS():
cherrypy.response.headers["Access-Control-Allow-Origin"] = "*"
if __name__ == "__main__":
cherrypy.tools.CORS = cherrypy.Tool('before_finalize', CORS)
cherrypy.quickstart(PyCachedAdmin(), config={'/': {'request.dispatch': cherrypy.dispatch.MethodDispatcher()}})
the server is running on localhost:8080. Now I've got a HTML file, available on localhost (default port 80) which loads jquery 1.9. I open the browser console to try the $.ajax to execute any AJAX request to the cherrypy server. I've been trying:
$.ajax({
url:'http://localhost:8080/',
type: "POST",
dataType: "json",
data: {command:"version"}
}).done(function(){
console.log('hej');
});
and
$.ajax({
url:'http://localhost:8080/',
type: "POST",
crossDomain: true,
dataType: "jsonp",
data: {command:"version"}
}).done(function(){
console.log('hej');
});
and
$.support.cors = true
and nothing worked. I'm getting either XMLHttpRequest cannot load http://localhost:8080/. Origin http://localhost is not allowed by Access-Control-Allow-Origin. or GET http://localhost:8080/?callback=jQuery19102827550224028528_1382823727186&command=version&_=1382823727187 404 (Not Found) when using jsonp (it's mysterious that it sends GET instead of POST). There is a few similar questions around, I tried them and these are my results (that something is still wrong).
PS the server is perfectly ok, since all curl tests pass. Something is wrong with the cross-domain stuff.
Are you activating the CORS tool?. You can use the tool by decorating the calling methods or set it on the configuration.
Given that the implementation of PyCachedAdmin is no expressed on the question I might guess that probably you are not enabling the tool, to do so you just need to change the config dictionary and make something like this:
cherrypy.quickstart(PyCachedAdmin(),
config={
'/': {
'request.dispatch':
cherrypy.dispatch.MethodDispatcher(),
'tools.CORS.on': True}})
Or if the methods that you are using on PyCacheAdmin has already been decorated or using _cp_config that extra configuration is not required and this answers will not help you.

how to call external json url and access it values

This returns a json object
http://developer.echonest.com/api/v4/artist/search?api_key=youAPIKey&name=radiohead
i tried this way but didn't work.
function cc() {
jQuery.ajax({
url: "http://developer.echonest.com/api/v4/artist/search?api_key=APIKey&name=radiohead",
type: "POST",
dataType: "json",
async: false,
success: function (data) {
console.log(data);
}
});
}
how can i call this url and access the object values using java script or jquery.
Due to Same Origin Policy, you can't access a resource on a different domain.
The solution is to proxy the request through a server side script on the same domain as your Javascript. JSONP is an option but only if the third party supports it.
As suggested by MrCode, you will need to use JSONP to access the data as your script is running in a different domain.
Echonest supports JSONP, using the format and callback options. You need to amend your url to include the format option.
http://developer.echonest.com/api/v4/artist/search?api_key=FILDTEOIK2HBORODV&name=radiohead&format=jsonp
If you amend the dataType option in your ajax options to jsonp then jQuery will append a callback parameter, which Echonest will use when sending the data back to you. You can then access the data in your success handler as required.
Unfortunately, you have posted your API key in your question, which means that lots of Stack Overflow users may be looking at your link, and screwing your access limit. You may need to wait for this question to become unpopular before your rate limit drops off again.

jQuery cross domain request still failing in IE, but using jsonp

My Ajax cross domain request is failing in IE 9 with "Access denied". I have read through several posts regarding this topic, and AFAIK it should work.
IE9 and jQuery 1.8.1
Call is async, jsonp and crossdomain, cache is false. These are the prerequisites I have found.
Works in latest Firefox and Chrome.
jQuery.support.cors is true
Even the response header is set: Access-Control-Allow-Origin:* (SO)
The returned JSON code would also be correct, have used a checker (also see 3.)
So why is this failing with Access denied? Any idea? Could it be because my code is called from within a "JavaScript" library, and not a <script></script> tag on the page?
What am I missing?
// The code is part of an object's method (prototype)
// code resides in a library "Mylib.js"
$.ajax({
type: 'GET',
url: url,
cache: false,
async: true,
crossdomain: true, // typo, crossDomain, see my answer below
datatype: "jsonp", // dataType
success: function (data, status) {
if (status == "success" && !Object.isNullOrUndefined(data)) { ... }
},
error: function (xhr, textStatus, errorThrown) {
// access denied
}
});
-- Edit -- based on Robotsushi's comments, some further research ---
Indeed, cannot find XDomainRequest in the jQuery source code (1.8.1)
If I do not set cors (jQuery.support.cors = true) I'll end up with a "No Transport" exception.
Still wondering why others obviously succeed with IE9 cross domain requests, e.g. here: jQuery Cross-Domain Ajax JSONP Calls Failing Randomly For Unknown Reasons In Some IE Versions
The way jQuery handles this, seems to be around the code below, but this is not called in my particular case, no idea why?
// Bind script tag hack transport
jQuery.ajaxTransport( "script", function(s) {
// This transport only deals with cross domain requests
if ( s.crossDomain ) {
A similar situation here in year 2010: Jquery $.ajax fails in IE on cross domain calls However, this should have been solved by the later jQuery versions.
Ok, working now. Couple of mistakes on my side:
It is crossDomain: true, dataType: "jsonp" , typo - missed capital letters.
JSONP requests are not transparent. The data are not simply JSON notation, but have to be wrapped in a Js function call (on the server side): see http://en.wikipedia.org/wiki/JSONP Basically this means, if you cannot modify the sent data, JSONP is not the right option for you.
All things considered, it works. So my personal checklist would be:
Use json if possible (e.g. with Chrome, FF, or most likely IE10). Make sure response header is set: Access-Control-Allow-Origin:*
If using jsonp, check: async: true, jsonp and crossdomain: true, cache is false, jQuery.support.cors is true These are the prerequisites I have found.
Also make sure the jsonp response is a function call (JSON wrapped in function), not "just ordinary" JSON data.
I've had a similar issue trying to access some json that I'm storing on Google Cloud Storage and accessing using jQuery's ajaxing. This worked fine in Chrome and Firefox, but I was getting 'access denied' messages when testing in IE (9 and below).
The way I got around it was to use jsonP, explicitly:
re-write my json file to be a javascript file with a javascript variable to hold the json data, e.g.
(function (o) {
variableName = [json];
}(window.[nameSpace] = window.[nameSpace]|| {}));
include the url to the javascript file within the tag of the html file, e.g.
<script type="application/javascript" src="[url to javascript file]"></script>
Consume the data via it's variableName
Hope this helps :)
IE requires you to use XDomainRequest instead of XHR for cross site.
You can check out the easyXDM which is a js library that abstracts this process for you.
Alternatively see this :
Access denied to jQuery script on IE

Trouble performing simple GET request returning JSON with Javascript

I'm horrible at Javascript, so sorry in advance for what I'm going to go ahead and assume is an amazingly stupid question.
I'm simply trying to perform a GET request to GitHub's public repo API for a given user, and return the value as JSON.
Here's the function I'm trying to use:
function get_github_public_repos(username) {
var the_url = "http://github.com/api/v2/json/repos/show/" + username
$.ajax({
url: the_url,
dataType: 'json',
type: 'get',
success: function(data) {
alert('raw data: ' + data)
var json_response = $.parseJSON(data);
alert(json_response);
}
});
}
This is returning Null for data. And in the console, I see Failed to load resource: cancelled. I know the URL is correct, because if I run curl on the url, it returns the expected data.
jQuery's ajax function supports JSONP which allows cross-domain requests (which you need because you're trying to request data from github.com from another domain). Just change the dataType from 'json' to 'jsonp';
function get_github_public_repos(username) {
var the_url = "http://github.com/api/v2/json/repos/show/" + username
$.ajax({
url: the_url,
dataType: 'jsonp',
type: 'get',
success: function(data) {
var json_response = data;
alert(data);
}
});
}
UPDATE: It's import to note that the end pint (in this case github.com's API) has to support JSONP for this to work. It's not a guarnateed solution for ANY cross-domain request as pointed out in the comments.
JavaScript is subject to cross-domain restrictions when making requests on a different server.
Well, unless you run your code in the github.com domain, that won't work.
You can use simle ajax only in your domain.
One solution is to create a proxy for it. Make a page on your server that does one thing, gets your requested (out of domain) content with curl, and prints it. Then you call this proxy with ajax.
The XmlHttpRequest object (which $ajax uses) cannot download content from a different domain due to the same origin policy. You would need to use something such as JSONP to be able to do this from a browser.
As the others have said, you cannot execute ajax on a remote domain.
You will need to write a server sided script on your domain (such as php), that will do the dirty work retrieving the information needed from the github domain.
Then, use your ajax to query your server side script for the information.
I know the URL is correct, because if
I run curl on the url, it returns the
expected data.
Use that idea to get your ajax working. Create a proxy page on your site that uses curl to retrieve the data you want, then have your "the_url" variable point to that page on your site. Cross-domain restrictions prevent you from being able to use ajax in the manner you attempted.

Parse XML response from API, Javascript, Ajax

I have a rails app and i wanna to parse the xml response from API using Javascript (ajax).
I tried:
$(document).ready(function()
{
$.ajax({
type: "GET",
url: "http://localhost:3000/users/mike.xml",
dataType: "xml",
success: parseXml
});
});
function parseXml(xml)
{
...
}
but don't work. When i am changing the 'url' with a local xml file e.x url: 'data.xml',
works fine!
How can i parse this response?
any help will be highly appreciated :-)
As Max suggested, it would be very helpful to install and use Firebug in a Firefox browser so you can watch the GET request and response. There isn't a lot to go on from your question, but it sounds like a problem on the "server" end.
When you say it doesn't work, do you mean parseXml(xml) isn't called? In your AJAX request, you define a success handler - if your GET request is failing then that handler is never called. I've found it's more useful to define the general callback ('complete' for JQuery, which it kind of looks like you're using) since it will get called no matter what the response. Then you just check to for success or failure yourself and take appropriate action.
Try removing the ".xml" from your URL. I believe AJAX calls accept xml response by default, so having xml in your request header as well as your URL might be confusing the controller. That's just a guess though.
If the URL is not on the same domain as your page with the JavaScript, your browser will prevent it from working because of the cross domain security policy. Check that you are rendering the page via a URL that looks exactly the same as the one you are requesting in your ajax call (so in the localhost example make sure you aren't running your server on a 127.0.0.1 URL, or something like that)

Categories

Resources