JSON and JSONP in jQuery - Back to Basics

Posted by: Suprotim Agarwal , on 3/2/2015, in Category jQuery and ASP.NET
Views: 38931
Abstract: Simple examples of consuming JSON and JSONP from a local and remote server, clearing some concepts along the way.

Now-a-days, it’s fairly common to request data in JSON format. It’s lighter-weight than XML, very easy to work as Ajax responses, when dealing with complex data and has generally speaking, become the most popular way of transferring data.

If you are new to Ajax as well as jQuery’s implementation of Ajax and JSON/JSONP, read Getting started with jQuery $.ajax() – Back to Basics  before you proceed further.

Using jQuery to get JSON data from the server is extremely easy. In this article, we will see a simple example of consuming data from a local URL and remote URL that returns data in JSON format. For our first example, we will take a JSON containing country names and populate a DropDown/HTML Select box with the values.

Create a new file called ‘SimpleJSON.html’. Here’s a snapshot of the JSON that we will be consuming. Save this file as countries.json:

{
    "countries": {
        "country": [
            {
                "id": 1,
                "cname": "Japan",
                "capital": "Tokyo"
            },
            {
                "id": 2,
                "cname": "India",
                "capital": "Delhi"
            },
            ...
        ]
    }
}

The barebones syntax of using $.ajax() to consume this JSON is as follows.

<script>
    $(function () {
        $.ajax({
            "url": "/scripts/S9/countries.json",
            "type": "get",
            "dataType": "json"
        })
        .done(function (data) {

        })
        .fail(function(jqXHR, status, error) {

        })
    });
</script>

We will implement the code that goes into done() and fail() in a bit.

In the example above, we are passing in an object of arguments/options to $.ajax(). The first argument is a local URL - "scripts/countries.json”. The next argument is the type of request to make, in our case GET, since we are only planning to read the data. The third argument is dataType which represents the type of data returned to you.

The jqXHR object returned by $.ajax() implements the Promise interface (as of jQuery 1.5 and above). So here we are using the Promise methods done() and fail() of the jqXHR object.

  • jqXHR.done(function( data, textStatus, jqXHR ) {})
  • jqXHR.fail(function( jqXHR, textStatus, errorThrown ) {});
  • jqXHR.always(function( data|jqXHR, textStatus, jqXHR|errorThrown ) { });

where data is the response from the server, in our case JSON.

textStatus is a string denoting the status like “success” "notmodified", "error", "timeout", "abort", or "parsererror" and

jqXHR returns the jqXHR object.

If you are still using the jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks, then please note that these have been deprecated in jQuery 1.8. Use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.

With the basic structure defined, let’s implement the code in the .done() and .fail() method.

.done(function (data) {
    var options = $("#country");
    $.each(data.countries.country, function (idx, val) {
        options.append($('<option />', { value: idx, text: val.cname }));
    });
})
.fail(function(jqXHR, status, error) {
    console.log("status:", status, "error:", error);
})

Here I am caching $(“#country”) outside the loop for a slight performance benefit. I then use $.each to loop over each country and execute a function for each element. The function takes two parameters. The first is the index of the item and the second is the item itself. We finally do options.append to add each country name to a DropDown list.

s9-simple-json

As of jQuery 1.9, an empty response is rejected. Your server should return a response of null or {} instead.

Using $.getJSON shorthand method

jQuery provides a shorthand method for fetching JSON data: $.getJSON. It’s called a shorthand method as behind the scenes it calls $.ajax() and has a shorter syntax. The basic version of this method accepts a URL to the JSON file and a success parameter that consists of a callback function that will be called if the request is successful.

Here’s the same code using $.getJSON

$(function () {
    $.getJSON('/scripts/S9/countries.json',
    function (result) {
        var options = $("#country");
        $.each(result.countries.country, function (idx, val) {
            options.append($('<option />', { value: idx, text: val.cname }));
        });
    });
});

If you observe there’s no error callback defined. This is because getJSON supports a callback function only for requests that have succeeded. In real applications, errors occur and it’s a good habit to handle these errors. For this reason, I recommend to use the $.ajax() method and not the shorthand method that we just saw. I have used the shorthand method in this article for educational purposes.

There is no equivalent $.postJSON() method.

Live Demo: http://www.jquerycookbook.com/demos/S7-Ajax/53-SimpleJSON.html

 

A Simple JSONP Example

On many occasions, you may come across a requirement to request data from a remote website. These websites provide APIs that accept requests and send back a response. For security reasons, Ajax requests are limited to the same domain or also known as the same origin. In this context, an origin is the combination of three components: URL protocol, hostname and port. If two URLs have the same components, then they are within the same origin, however if any of the components is different, then they are of different origins or cross origin.

For eg: http://www.jquerycookbook.com and https://www.jquerycookbook.com are of different origins as the protocol differs - http and https.

This cross domain policy is enforced to reduce the risks of a cross-site scripting (CSS) attack, where the browser or user maliciously attempts to contact another site.

So how do you make Ajax requests outside your domain or in other words, how do you make cross-domain Ajax requests? jQuery makes it possible to request JSON data outside the domain by requesting JSON with Padding – also known as JSONP. In your Ajax request, if the data is marked as JSONP, jQuery appends a query string parameter callback=? to the URL. Alternatively, you can also manually add &jsoncallback=? to the URL which notifies the calling site that you want to receive JSONP data. Doing so also lets jQuery’s $.getJSON() function treat this request as if the browser was requesting an external JavaScript file. Simply put, JSONP is JSON wrapped inside a function call

Let’s see this in action. We will use the Ziptastic API service (http://ziptasticapi.com/) which accepts a US zip code and returns City and State based on it and gives the data back in JSONP format which you can consume in your jQuery application.

The format of the API call is : http://ziptasticapi.com/zipcode?callback=mycallback

An important thing to observe in this API url is that ZipCode is part of the url.

Create a file ‘SimpleJSONP.html’. Let’s declare two text boxes, one for the Zip code and the other for the City.

<body>
    <label for="zip">ZIP:</label>
    <input type="text" name="zip" id="zip"/>

    <label for="city">City:</label>
    <input type="text" name="city" id="city" />
</body>

Here’s the code to consume this API:

<script type="text/javascript">
    $(function () {
        $("#zip").on('change', function () {
            var zip = $(this).val();
            var url = "http://ziptasticapi.com/" + zip + "?callback=?";
            $.getJSON(url, null, function (result) {                   
                if (result.city)
                    $("#city").val(result.city);
            });
        });
    });
</script>

We start by monitoring the change event on the Zip Code textbox. We then use val() to retrieve the value of the Zip Code entered by the user in a variable zip. Since the Ziptastic API is of the format http://ziptasticapi.com/zipcode?callback=mycallback, in our code, we are concatenating the zip code in the url, followed by the callback parameter to tell the API to return JSONP.

We then use $.getJSON and pass in the url and a success parameter result that consists of a callback function that will be called if the request is successful. Inside the callback function, we check the value of the city and if it exists, update the value of the City textbox.

Run the example, enter a zip code say 94101 and hit tab. You will see that the City textbox populates with the City name

s9-jsonp-ziptastic

Live Demo: http://www.jquerycookbook.com/demos/S7-Ajax/54-SimpleJSONP.html

Can cross-domain Ajax Requests work without specifying the callback parameter?

With some websites, you may observe that cross-domain Ajax request works even when you are not using JSONP explicitly. So how’s that possible? In such cases, always check the HTTP Response Header returned by the server. If the server responds with an Access-Control-Allow-Origin: * it means that the resource can be accessed by any domain in a cross-site manner.

Let’s try this with the ziptastic service by removing the callback from the url.

var url = "http://ziptasticapi.com/" + zip;

As you can see, we are not specifying the callback in this url string. Run the example and you will see that the output remains the same. In the Google Chrome Developer Tools (Ctrl + Shift + I), if you see the HTTP Response Header returned by Ziptastic, you will observe that it responds with an Access-Control-Allow-Origin: * which means that the resource can be accessed by any domain in a cross-site manner.

s9-jsonp-sameorigin

So make sure you keep this point in mind while making JSONP calls. I generally use the callback parameter when and where I can.

JSONP is actually a hack and thus contains security risks. A lack of proper error handling mechanism also makes it tough to debug, when calls don’t work as expected.

Take a look at my new book The Absolutely Awesome jQuery Cookbook which contains scores of practical jQuery/jQueryUI recipes you can use in your projects right away.

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for Sixteen consecutive years. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that offers Digital Marketing and Branding services to businesses, both in a start-up and enterprise environment.

Get in touch with him on Twitter @suprotimagarwal or at LinkedIn



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by chandan on Wednesday, March 4, 2015 7:45 AM
Nice article, got very good knowledge about Ajax!!
Comment posted by Steve Curran on Wednesday, April 1, 2015 3:00 PM
This helped consolidate my knowledge.
Thanks !
Comment posted by Suprotim Agarwal on Friday, April 3, 2015 6:24 AM
@chandan @steve Thank you for your feedback!
Comment posted by Timothy on Wednesday, April 8, 2015 12:40 PM
Please how can i get access to the json file in my own domain
And how should the json file be structured to allow for the callback parameter
Thanks
Tim
Comment posted by Suprotim Agarwal on Thursday, April 9, 2015 5:36 AM
@Timothy What's the path to your JSON file and how are you accessing it.

From your question I am assuming you want to pass a parameter. Look at the ziptastic example which passes a param.

If I have misunderstood your question, ask me again with some code to see.