JSON with Padding, or JSONP, exploits a loophole in the same-origin policy which browsers employ to prevent access to resources passed via scripts from foreign sites. Instead of passing JSON-formatted data back in an Ajax call, as we do when using Ajax from within our own site, the JSONP response instead returns the JSON-formatted data as the argument of a callback function - "padded" (the "P" in JSONP) by the callback function. Most of the time, our JSONP call to the external resource specifies the name we want for the callback function; on our end, as we receive the "padded" JSON-formatted data, we then invoke the function to process the data. Without this padding - without wrapping the JSON data in a callback function - the security policies in place in our browsers would not allow us to access the foreign resources.
We we've seen previously in this course, a non-JSONP Ajax call might result in the following data returned from another page on our own domain:
With JSONP, the return content might look as such:
On our end, we treat the returned data as a call to callbackfunction() and, if we define what callbackfunction() should do, then we can make use of the JSON-formatted data returned by the foreign server. For example:
jQuery makes using JSONP quite easy, abstracting away some of the internal aspects of the remote calls, so we'll use jQuery. We'll again use jQuery's $.ajax method; the only difference between the earlier examples and our use with JSONP are two parameters for the $.ajax method:
Let's look at an example using a JSONP call to Yahoo! using their Query Language service.
Note that we need not start up the Node.js server here, since we are accessing remote data; simply open the file CORSJSONP/Demos/jsonp-yahooquery.html in your browser directly.
Enter a zip code and a type of establishment for which to search (e.g. "pizza", "movies", "supermarkets").
We add a jQuery
click handler on the button: when the button is clicked, three things happen:
zipis assigned the value entered in the
queryis assigned the value entered in the
$.ajax call, we specify
http://query.yahooapis.com/v1/public/yql as the
callback is given as the name for the
jsonp callback function (as required by this Yahoo! service), and
dataType: "jsonp" tells the function that we expect to receive a JSONP-formatted result.
The Yahoo! Query Language service offers a variety of available resources: we choose here to ask for "local" results (usually businesses). As such, as we pass - via the
data parameter, a query that sends along the user-supplied zip code and query. We might, for instance, ask for all "pizza" places near a zip code like "13214" using the query
select * from local.search where zip='13214' and query='pizza'.
success callback function - a parameter of the
$.ajax method - we define how we will handle the response. Key here is to discover the schema by which the results are returned. Either by using a tool like Firefox's or Chrome's inspector, or by using Yahoo!'s Query Language console (or both), we find that the set of results in which we are interested are returned in an array "query.results.Result"; thus, our code iterates (
response.query.results.Result, appending a paragraph to
#Content for each returned result:
The next exercise asks you to try out using JSONP with jQuery.