2

I am trying to do a cross domain request within jquery, in a function like the one found in this gist

I thought I had incorrect JSON, but this is what I get from the response:

{"status":"OK","errorMessage":"","numberOfResults":10,"suggestions":[{"url":"http://dbpedia.org/resource/Bassiana","label":"Bassiana","owner":0},{"url":"http://dbpedia.org/resource/Julia_Soaemias_Bassiana","label":"Julia Soaemias Bassiana","owner":0},{"url":"http://dbpedia.org/resource/Julia_Bassiana","label":"Julia Bassiana","owner":0},{"url":"http://dbpedia.org/resource/Varius_Avitus_Bassianus_Marcus_Aurelius_Antoninus","label":"Varius Avitus Bassianus Marcus Aurelius Antoninus","owner":0},{"url":"http://dbpedia.org/resource/Bassianus_%28senator%29","label":"Bassianus (senator)","owner":0},{"url":"http://dbpedia.org/resource/Johannes_Bassianus","label":"Johannes Bassianus","owner":0},{"url":"http://dbpedia.org/resource/Julius_Bassianus","label":"Julius Bassianus","owner":0},{"url":"http://dbpedia.org/resource/Bassian_thrush","label":"Bassian thrush","owner":0},{"url":"http://dbpedia.org/resource/Bassianae","label":"Bassianae","owner":0},{"url":"http://dbpedia.org/resource/Bassian","label":"Bassian","owner":0}]}

How am I supposed to make it work? It seems the callback is never fired since the JSON is not valid.

mox601
  • 422
  • 2
  • 7
  • 23
  • That seems a valid JSON, at least to JSONLint. What kind of error do you get? – mamoo Oct 26 '11 at 13:28
  • can you post your $.post call? Also, if you are doing a cross-domain request, you probably should look at using JSONP instead of JSON. – jbabey Oct 26 '11 at 13:29

3 Answers3

2

The problem is not that it's invalid (as passing it though this site will confirm), it's that it's never "wrapped" in a callback method.

Look up JSONp.

If you were to call /getMyJSON?callback=myCallback your JSONP response should come back like:

myCallback({"status":"OK","errorMessage":"","numberOfResults" ...);

(Note that it's now wrapped in a function call that you should have defined on your page, and ready for processing the returned results).

Brad Christie
  • 100,477
  • 16
  • 156
  • 200
  • Also, check out a [previous answer I wrote up](http://stackoverflow.com/questions/6849802/jquery-getjson-works-locally-but-not-cross-domain/6849861#6849861) that describes the process a bit more in detail. – Brad Christie Oct 26 '11 at 13:31
  • I think you're on the right track here, but that's not always the case. You don't have to return JSONp to make a cross-domain request. JSON/HTML/etc. will return just fine if the proper allow-access headers are set. – JackWink Oct 26 '11 at 13:35
  • @JackWink: 99% of the time, the AJAX call won't return anything but an error response because it's going between different domains. Yes, you can play with headers and event client preferences to get beyond this, but the most efficient solution is to handle it as JSONp (IMHO) – Brad Christie Oct 26 '11 at 13:37
  • 1
    you're correct, and I'm not saying your answer is wrong, but I'm trying to say that he may not control the other domain, and if they haven't done JSONp, but set `Access-Control-Allow-Headers: *` then he'd be running in to trouble since it isn't wrapped in JSONp, but .getJSON() relies on the wrapper. – JackWink Oct 26 '11 at 13:46
  • so basically I _have_ to wrap the response in a function like this: `functionName()` ? There is no way to do this in JQuery? – mox601 Oct 26 '11 at 13:49
  • @mox601, not unless you control the other domain. You have to ensure the other domain allows cross domain requests, either by wrapping the returned JSON, making it JSONp, or by looking at the response headers they set for an 'Access-Control-Allow-Headers: *' You need one or the other to make the request from javascript. – JackWink Oct 26 '11 at 13:52
  • @mox601: Yes, and more importantly it needs to come from the server like that (or else any other bypasses are server-driven). You may be able to hack it and include a `document.write` and a ` – Brad Christie Oct 26 '11 at 13:53
  • Ok. I think I'll go ahead and edit the service to embed the response inside the function. – mox601 Oct 26 '11 at 13:55
  • 2
    @mox601: That will avoid most issues. Also, try to make it accept a "callback" url parameter so libraries can access it with as little re-configuration as possible (e.g. $.getJSON) – Brad Christie Oct 26 '11 at 13:57
1

A cross domain request needs to use JSONP. JSONP requests are actually sent as a script request and require that you supply a callback (and the callback parameter) so that the server can deliver a script which contains a call to your callback function as it's content. The way to do this with the getJSON call is to append &callback=? to your other URL parameters. This notes to jQuery that it must make a JSONP request and also instructs it to create an anonymous function that invokes your callback.

NOTE: the server must support JSONP as it needs to handle the response differently, i.e., returned as a script with the data supplied as the parameter to the callback. Services that support direct access via Javascript should support JSONP. If the service doesn't support JSONP, you'll need to proxy the request on your server, where you can request it as plain JSON since you don't have the cross domain browser restrictions.

$.getJSON('http://some.other.dom/controller/action?x=y&callback=?`, function(data) {
    // here the data is the deserialized JSON as an object
});
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
0

Thats not jsonp - jsonp includes the callback. The gist you looked at says nothing about being cross domain. You will have to look at the service and see what you need to do to get it to return jsonp not json.

Here is a sample call returning my last twitter feed:

http://twitter.com/status/user_timeline/rossdargan.json?count=1&callback=JSONPcallbackFunction

As you see the result gets wrapped in the JSONPcallbackFunction:

JSONPcallbackFunction([{"place":{"bounding_box":{"type":"Polygon","coordinates...
Ross Dargan
  • 5,876
  • 4
  • 40
  • 53