Over a million developers have joined DZone.

Getting Started with JSON-P

· Java Zone

Navigate the Maze of the End-User Experience and pick up this APM Essential guide, brought to you in partnership with CA Technologies

During my college days I used XMLHttpRequest objects and their equivalents in the Microsoft world to make Ajax calls that were sent to the URL within the same domain. But with the advent of web services and a whole lot of mashups being developed, Ajax calls are not restricted to same domain but cut across different domains. When this cutting across domain boundaries happens, making an Ajax call using XMLHttpRequest will fail due to security enforcements implemented by the browsers. That’s when the idea of JSON-P i.e JSON with Padding came about.

In this post I will quote from different sources about JSON-P and then go ahead and implement examples that invoke the Stackoverflow API to retrieve the unanswered questions tagged ‘jsonp’

  1. What is JSON-P?
  2. Simple example for JSON-P
  3. Accessing Stackoverflow API using JSON-P


What is JSONP?

I am not going to restate its definition.  Instead, I'll quote its definition from different sources:

From Head First HTML5:

JSONP is a way to retrieve JSON objects by using the script tag. It’s also a way of retrieving data (again, in the form of JSON objects) that avoids the same-origin security issues we saw with XMLHttpRequest. JSONP is JSON data wrapped in JavaScript; typically, a function call.

From http://json-p.org/

One such mechanism which can request content cross-domain is the script tag. In December 2005, Bob Ippolito formally proposed JSONP (later dubbed JSON-P, or JSON-with-padding) as a way to leverage this property of script tags to be able to request data in the JSON format across domains. JSON-P works by making a script element (either in HTML markup or inserted into the DOM via JavaScript), which requests to a remote data service location. The response (the loaded “JavaScript” content) is the name of a function pre-defined on the requesting web page, with the parameter being passed to it being the JSON data being requested. When the script executes, the function is called and passed the JSON data, allowing the requesting page to receive and process the data.

From Wikipedia: http://en.wikipedia.org/wiki/JSONP

JSONP or “JSON with padding” is a communication technique used in JavaScript programs which run in Web browsers. It provides a method to request data from a server in a different domain, something prohibited by typical web browsers because of the same origin policy.

To summarize, JSONP is a communication technique to retrieve data from some URL and then leveraging the script tag to establish the communication and JavaScript to update the HTML.
There have been a lot of concerns about how secure JSONP is, but I don't want to get into those discussions as that is not the main motive of this post.

Now going forward, let me show JSONP in action using a simple example.

Simple example for JSONP

For a simple example I will make use of some resources from the chapter on JSONP in the Head First HTML5 book. I am going to make a JSONP call to a Javascript resource which in turns invokes the callback function declared in my Javascript source.

Lets look at the HTML source:

<html>
  <head>
    <title></title>
    <meta charset="UTF-8">
    <script src="simple.js"></script>
  </head>
  <body>
    <h1>JSONP Simple Demo</h1>
    <!-- we will update the data here -->
    <div id="jsonp"></div>
  </body>
</html>

The interesting thing happens in the JavaScript code.

//simple.js
window.onload = function(){
  //Get the head element.
  var head = document.getElementsByTagName("head")[0];
  
  //url for the javascript resource for JSONP call.
  var url = "http://wickedlysmart.com/hfhtml5/chapter6/dog3.js";
  
  //Appending the script tag to the head element.
  //This triggers a JSONP call to get the data.
  var scriptTag = document.createElement("script");
  scriptTag.setAttribute("src",url);
  head.appendChild(scriptTag);
}

//Method invoked by JSONP
function animalSays(animal){
  var div = document.getElementById("jsonp");
  div.innerHTML = animal.type +" says "+ animal.sound;
}

The “http://wickedlysmart.com/hfhtml5/chapter6/dog3.js” contains:

var animal = { "type": "dog", "sound": "woof" };
animalSays(animal);

The above JavaScript code:
1. Creates a JSON object
2. Invokes the callback by passing the JSON object.

Now the question is, where is the animalSays method declared? If you have carefully looked at simple.js you can see that the method animalSays has been declared. When the JavaScript in the above URL is requested using JSONP technique by dynamically adding the script, the javascript is executed in the browser which contains the definition of the animalSays method.

The animalSays method retrieves the JSON object and then populates the HTML with the data in the JSON object.

Lets look at a better example.

Accessing Stackoverflow API using JSONP

Details of the Stackoverflow API for unanswered questions can be found here. The URL for accessing unanswered questions tagged ‘jsonp’ is: https://api.stackexchange.com/2.1/questions/unanswered?order=desc&sort=activity&tagged=jsonp&site=stackoverflow

The above URL returns some JSON data, but how does it help in making use of JSONP? One can append another parameter to the above URL called “callback” which will take the name of the JavaScript method that will be invoked once the URL is loaded by the script tag.

Lets take a look at the HTML code:

//sflow.html
<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="sflow.js"></script>
  </head>
  <body>
    <div>Unanswered questions tagged 'jsonp'</div>
    <!-- placeholder for updating the questions -->
    <div id="questions">
    </div>
  </body>
</html>

The JavaScript code has 2 parts:

  • Part-1: Loading the URL which contains the data and the function invocation.
window.onload = function() {
  var head = document.getElementsByTagName("head")[0];
  var script = document.createElement("script");
  
  var url = "https://api.stackexchange.com/2.1/questions/unanswered?" +
          "order=desc" +
          "&sort=activity" +
          "&tagged=jsonp" +
          "&site=stackoverflow" +
          "&callback=listUnansweredQuestions";
  //The URL is loaded by including it in the script tag and adding to the DOM.
  script.setAttribute("src", url);
  head.appendChild(script);
}
  • Part-2: Defining the callback which gets the data and then updates the HTML
function listUnansweredQuestions(questions) {
  var div = document.getElementById("questions");
  var ul = document.createElement("ul");
  div.appendChild(ul);
  for (var i = 0; i < questions.items.length; i++) {
    var question = questions.items[i];
    var li = document.createElement("li");
    li.innerHTML = "<a href="+question.link+">"+question.title+"</a>";
    ul.appendChild(li);
  }
}

The complete Javascript code would be:

//sflow.js
window.onload = function() {
  var head = document.getElementsByTagName("head")[0];
  var script = document.createElement("script");

  var url = "https://api.stackexchange.com/2.1/questions/unanswered?" +
          "order=desc" +
          "&sort=activity" +
          "&tagged=jsonp" +
          "&site=stackoverflow" +
          "&callback=listUnansweredQuestions";

  script.setAttribute("src", url);
  head.appendChild(script);
}

function listUnansweredQuestions(questions) {
  var div = document.getElementById("questions");
  var ul = document.createElement("ul");
  div.appendChild(ul);
  for (var i = 0; i < questions.items.length; i++) {
    var question = questions.items[i];
    var li = document.createElement("li");
    li.innerHTML = "<a href="+question.link+">"+question.title+"</a>";
    ul.appendChild(li);
  }
}

The output for the above HTML and Javascript would be:
JSONP_result
If you have any issues in running any of the sample code shown in the post above, please get in touch via the comments below.


Thrive in the application economy with an APM model that is strategic. Be E.P.I.C. with CA APM.  Brought to you in partnership with CA Technologies.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}