0

I already have a .json object in a server. It is correct and has no syntax errors (valid json). I want to call this object through JSONP because it resides in a server different from my app's.

I think I understand how to achieve it client-wise, but I have no idea what to do in relation to the server part. I am having errors all the time when following the info already on the web. Any help?

JZweige
  • 721
  • 2
  • 9
  • 15

2 Answers2

6

JSONP is basically a "hack" to allow sites to load data and ignore the same-origin policy. It works by appending a <script> tag to your page.

The de facto way is to send a callback in your request. The server would then take that name and generate a JS file that calls that function with the data.

Using jQuery, you can make a JSONP call by simply appending ?callback=? to your URL when doing $.getJSON.

Example:

$.getJSON('http://YourSite.com/path/to/json.php?callback=?', function(data){
    console.log(data); // this will be parsed for you
});

Or, you can use the full $.ajax method:

$.ajax({
    url: 'http://YourSite.com/path/to/json.php',
    dataType: 'jsonp', // this tells jQuery to add "callback=?" for you
    success: function(data){
        console.log(data); // this will be parsed for you
    }
});

Instead of makning an AJAX call, jQuery will actually append:

<script src="http://YourSite.com/path/to/json.php?callback=jQuery12345"></script>

to your page (note: jQuery12345 will be randomly generated).

Then on your server, you need to respond with a valid JavaScript file. It should contain a call to the callback function passed in the query string. Something like this:

jQuery12345({your: ['json', 'data']});

An example in PHP (adapt to whatever server-side language you use) could be:

$array = ['a' => 1, 'b' => 2,'c' => 3];
$callback = $_GET['callback'];

header('Content-type: text/javascript');
echo "{$callback}(".json_encode($array).");";

That's all there is to it. See the Wikipedia page on JSONP for more info: http://en.wikipedia.org/wiki/JSONP

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
6

JSONP has nothing to do with JSON. Here's a simple (but useless) example:

  • The client makes a script element: <script src="http://example.com/foo.js>. This causes the browser to fetch foo.js from example.com.

  • The server hears the request for foo.js. The server serves the contents of foo.js to the client (suppose it's just alert(1)).

  • The client gets the contents of foo.js and runs those contents as a script. (So, the client does alert(1).)

How is this useful? Well, you can pass arguments with your request to foo.js:

  • The client does <script src="http://example.com/foo.js?arg=123>

  • The server hears a request for foo.js?arg=123. The server does something with that arg value -- let's suppose it multiplies it by 2 (but it could do something useful, like look up the username for the user with uid 123). The server then sends back the script content alert(246).

  • **The client runs the script from the server and alerts 246.

Okay, this is great if I want the client to alert stuff, but how can I do something useful? There's just one last leap we have to make: provide the name of a client function as an argument:

  • The client defines a function myFunc as: function myFunc(a) { alert(a) }

  • The client does <script src="http://example.com/foo.js?callback=myFunc&arg=123>

  • The server hears the request for foo.js?callback=myFunc&arg=123, and its server-side scripting knows it should use the callback argument as the name of the function called in foo.js. The server sends back the script content myFunc(246).

  • The client runs myFunc(246). Here, we've specified myFunc to just alert its argument, but you could have it do anything you like.

That's how JSONP works. The client provides arguments to the server in a script URL, including the name of a client-side function, and the server sends back a script (not JSON!) for the client to run. Of course, the resulting script can contain JSON in it, like myFunc({ 'foo' : 5 }), but ultimately, that JSON is just part of the script content.

apsillers
  • 112,806
  • 17
  • 235
  • 239
  • Good basic description. I like how you noted that you can return any value in the callback, not just an object. :-) – gen_Eric Oct 18 '13 at 19:31