Can anyone explain what JSONP is, in layman terms?

Someone picture Someone · Oct 1, 2010 · Viewed 141.7k times · Source

I know JSONP is JSON with padding.

I understand what JSON is, and how to use it with jQuery.getJSON(). However, I do not understand the concept of the callback when introducing JSONP.

Can anyone explain to me how this works?

Answer

Matt picture Matt · Oct 1, 2010

Preface:

This answer is over six years old. While the concepts and application of JSONP haven't changed (i.e. the details of the answer are still valid), you should look to use CORS where possible (i.e. your server or API supports it, and the browser support is adequate), as JSONP has inherent security risks.


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

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

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 object is passed as an argument to a callback function.

JSON:

{ "bar": "baz" }

JSONP:

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

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

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 could be caught by wrapping the attempt to evaluate the responseText in a try/catch statement. Because of the nature of a JSONP response, parse errors in the response will cause an uncatchable JavaScript parse error.

Both formats can implement timeout errors by setting a timeout before initiating the request and clearing the timeout in the response handler.


Using jQuery

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

By default jQuery requires 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 question mark ? in &callback=? with the name it has assigned.


Comparable JSON/JSONP Implementations

The following assumes a response object { "bar" : "baz" }

JSON:

var xhr = new XMLHttpRequest();

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

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

JSONP:

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

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

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