views:

166

answers:

3

I known JSONP is (JSON padding) . I Know what is JSON and using it in $.getjson in jquery is also known But using jsoncallback cannot be understood and what is JSONP

+2  A: 

Say you had some URL that gave you JSON data like:

{'field': 'value'}

...and you had a similar URL except it used JSONP, to which you passed the callback function name 'myCallback' (usually done by giving it a query parameter called 'callback', e.g. http://example.com/dataSource?callback=myCallback). Then it would return:

myCallback({'field':'value'})

...which is not just an object, but is actually code that can be executed. So if you define a function elsewhere in your page called myFunction and execute this script, it will be called with the data from the URL.

The cool thing about this is: you can create a script tag and use your URL (complete with callback parameter) as the src attribute, and the browser will run it. That means you can get around the 'same-origin' security policy (because browsers allow you to run script tags from sources other than the domain of the page).

This is what jQuery does when you make an ajax request (using .ajax with 'jsonp' as the value for the dataType property). E.g.

$.ajax({
  url: 'http://example.com/datasource',
  dataType: 'jsonp',
  success: function(data) {
    // your code to handle data here
  }
});

Here, jQuery takes care of the callback function name and query parameter - making the API identical to other ajax calls. But unlike other types of ajax requests, as mentioned, you're not restricted to getting data from the same origin as your page.

sje397
+1  A: 

It appears to allow cross domain script injection

http://remysharp.com/2007/10/08/what-is-jsonp/

methodin
This is only a tiny part of what jsonp is.
+10  A: 

JSONP is a method commonly used to bypass the cross-domain policies in web browsers (You are not allowed to make AJAX requests to a webpage perceived to be on a different server by the browser).

JSON and JSONP behave differently on both the client and the server. JSONP requests are not dispatched using the XMLHTTPRequest (and the associated browser methods), instead a <script> tag is created, which source is set to the target URL. This script tag is then added to the DOM (normally the <head>).

JSON Request:

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200) {
    // success
  };
};

xhr.open("GET", "somewhere.php", true);
xhr.send();

JSONP Request:

var tag = document.createElement("script");
tag.src = 'somewhere_else.php?callback=foo';

document.getElementsByTagName("head")[0].appendChild(tag);

The difference between a JSON response and a JSONP response, is that the JSONP response is formulated such that the response object is passed as an argument to a callback function.

JSON:

{
    "foo": "bar"
}

JSONP:

yourCallbackFunction({
    "foo": "bar"
});

This is why you see JSONP requests containing the "callback" parameter; so the server knows the name of the function to wrap the response around.

This function must exist in the global scope at the time the <script> tag is evaluated by the browser (once the request has completed).


Another difference to be aware of between the handling of a JSON response and a JSONP response, is that any parse errors in a JSON response can potentially be caught (by wrapping the attempt to evaluate the responseText in a try/catch statement). Because of the nature of a JSONP response however, parse errors in the response will yield an uncatchable JS Parse error. Both formats however, can implement timeout errors (by setting a timeout before initiating the request, and clearing the timeout in the response handler.


The usefulness of using jQuery to make JSONP requests, is that jQuery does alllllllll of the work for you in the background.

jQuery requires (by default), for you to include &callback=? in the URL of your AJAX request. jQuery will take the success function you specify, assign it a unique name and publish it in the global scope. It will then replace the ? in &callback=? with the name it's just assigned the function.


Comparable JSON/ JSONP Implementations (assuming response object is {"foo":"bar"}:

JSON

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {
  if (xhr.readyState == 4 && xhr.status == 200) {
    document.getElementById("foo").innerHTML = eval('(' + this.responseText + ')').foo;
  };
};

xhr.open("GET", "somewhere.php", true);
xhr.send();

JSONP:

function foo(response) {
  document.getElementById("foo").innerHTML = response.foo;
};

var tag = document.createElement("script");
tag.src = 'somewhere_else.php?callback=foo';

document.getElementsByTagName("head")[0].appendChild(tag);
Matt
Great explanation, +1.
Skilldrick