What is JSON?

JSON stands for JavaScript Object Notation. It is an open, text-based format designed for lightweight data exchange between different systems. JSON is a subset of JavaScript's object literal notation representing simple data structures and objects. The array elements and object member values in JSON are limited to numbers, strings, Boolean values, objects, arrays, and null. This is different from JavaScript object literals where values of array elements and object members can be any JavaScript expression, including function definitions.

The beauty of JSON standard lies in its simplicity and the fact that it is very compact. Let's look at an example. Here we have the JSON representation of a student object.

{
   "firstName": "Kim", 
   "lastName": "Taylor",
   "studentCode": 7
}

JSON objects can be nested. Below is a student including its image, which is an object itself:

{
   "firstName": "Kim", 
   "lastName": "Taylor",
   "studentCode": 7,
   "image":
    {
        "url": "images/007.jpg",
        "width": 150,
        "height": 150
    }
}

A JSON-formatted string always has a single top-level item which is either an object, with curly braces {}, or an array, with square brackets []. The earlier examples are objects. The next example shows an array with three elements:

[
    "Red", 
    "Green",
    "Blue"
]

The elements in a JSON array can be of different type. Here is an example of an array with four elements, each one of a different data type:

[
    "Blue",              // string
    {                    // object
      "id": "001",
      "name": "IBM"
    },
    2.4,                 // number
    True                 // Boolean 
]

JSON doesn't natively represent complex data types like functions, date, and time. To represent date and time values, you can either use an ISO-formatted string or a number (number of milliseconds in UTC since January 1, 1970). Note that these are just conventions: JSON standard does not dictate rules for encoding date and time values.

Although JSON is a subset of the standard JavaScript object notation, it is a language-independent data format. JSON parsers that parse and generate JSON data are readily available for most programming languages. Visit www.json.org and you will find a broad range of available JSON libraries.

JSON maps very well to data structures that most programming languages support. A JSON object is an unordered collection of name-value pairs which easily maps to associative arrays (such as Dictionary, Map, and Hash) in other languages. Similarly, a JSON array is an ordered list of values which nicely maps to any programming language's array or list types.

Because of these characteristics, JSON is ideal as a data exchange format between disparate applications. There are few if any parsing complexities. It is very easy, for example, to convert a C# object to JSON and then pass it to a Python or JavaScript application.

Today, JSON is widely used for serializing and sending structured data over a network, essentially replacing XML. Most commonly, JSON is used in Ajax communications between a server and the web browser. JSON-formatted data is lightweight and JavaScript can parse it very easily making it ideal for Ajax-style web applications. The data that is transmitted is encoded as JSON objects, and those JSON objects can be transformed with little effort into true JavaScript objects on the browser.





XML versus JSON

Over the last few years, XML has lost ground to JSON as a popular data exchange format. In XML there is no concept of data types. All element values are strings. To add type information, you have to apply the XML Schema typing layer on the top of XML. This adds complexity to your application when you read the values within the XML code. JSON objects provide structure to your data and their values are typed as numbers, strings, Boolean values (true and false), null, nested objects, or arrays. In XML, arrays and objects have to be represented by convention while JSON supports them natively.

JSON also has a clear edge over XML when it comes to parsing data in JavaScript. With XML, data is parsed manually requiring code that transforms parsed text into JavaScript objects. On the other hand, with JSON you can immediately transform JSON-formatted data into JavaScript objects using the JSON.parse() method. Parsing JSON-formatted data is very fast because it is done by the JavaScript engine itself.

While XML parsers are available in all modern browsers, you have to be very careful with cross-browser differences. How you create the DOM that will load the XML depends on which browser you are using. On the other hand, JSON is very well supported by all browsers.

Here is a comparison of a student record formatted as XML and as JSON.

 XML format  JSON format
<student>
<firstName>Kim</firstName>
<lastName>Taylor<lastName>
<studentCode>7<studentCode>
</student>
{
    "firstName": "Kim",
    "lastName": "Taylor",
    "studentCode" : 7
}

As you can see, the XML is larger than JSON. XML documents tend to be lengthy because of the presence of both start and end tags and namespaces. JSON, on the other hand, is lightweight and its syntax is rather terse. When sending a large amount of data over a network, JSON is preferred as this will significantly improve performance.

Furthermore, XML has a bit of a learning curve because it is typically used in conjunction with other technologies, including XML Schema, XPath, XSLT, etc. JSON, on the other hand, is easy to learn especially for developers that have a background in JavaScript.

An advantage of XML is that it provides native support for namespaces which reduces the risk of ambiguity when merging documents from different sources. JSON has no notion of namespaces and hence poor extensibility. A possible workaround to prevent naming collisions is to prefix object member names with a context.





JSON.parse() and JSON.stringify()

Instead of employing a third-party JSON parser library, the JavaScript engine can itself be used to process the JSON-formatted data and convert it to native JavaScript objects. As you know, JavaScript has an eval() function that is designed to evaluate a JavaScript expression and return its value. Since JSON is mostly syntactically correct and valid JavaScript code, an effortless approach to execute JSON data would be to use eval().

However, eval() is not recommended because your application would expose itself to all sorts of security vulnerabilities. Even if the source is trusted, a security breach at the trusted source's end could cause a code injection attack in your application. So, eval() should be avoided.

The recommended solution is to use a JavaScript-based JSON parser library in your client code which essentially is a wrapper around eval(). Before the parser evaluates, it validates the input string as JSON and makes sure that it does not contain arbitrary executable JavaScript code thereby preventing potentially malicious code from getting executed.

As a secure alternative to eval(), EcmaScript5 provides the native JSON.parse() which is exclusively meant to parse JSON data and not JavaScript. It is supported by most web modern browsers. Alternatively, you can use json.js, or better, json2.js (downloadable from https://github.com/douglascrockford/JSON-js) which minified is just 2.5K. The JSON.parse() method first validates the JSON-formatted text string and then converts it into a JavaScript object.

Deserializing JSON text into the JavaScript object with JSON.parse()

Here is an example of JSON.parse() in action.

var json = '{ "firstName":"Kim", "lastName":"Taylor", "studentCode":7 }';
var student = JSON.parse(json);
alert(student.firstName + " " + student.lastName);   // => Kim Taylor

The optional reviver argument to JSON.parse() is a function that filters and transforms the results . It accepts two arguments, key and value. The reviver is invoked with each of the key-value pairs generated by the parse, and its return value is used instead of the original value. If the reviver returns what it received, the structure is not modified. If the reviver returns null or undefined, the property is deleted from the result. In the example below reviver transforms all date strings to date objects (and transforms these from Greenwich Mean Time (Zulu time) to local time in the browser's time zone.

function reviver (key, value) {
   var num = Date.parse(value);
   if (num) {
       return new Date(num);
   }
   return value;
}
var json = '{ "firstName":"Kim", "registrationDate" : 
                                 "2012-05-20T11:20:00.000Z" }';
var student = JSON.parse(json, reviver);
alert(student.registrationDate);    // => Sun May 20 06:20:00 CDT 2012

Serializing objects into the JSON format with JSON.stringify()

The JSON.stringify() method does the reverse of JSON.parse() and converts a JavaScript object into a JSON-formatted string. The optional replacer argument to JSON.stringify() is a function filters and transform the way a value is stringified. It accepts two arguments, key and value. In the example below, the properties with scores less than 40 are filtered out:

var scores = { "Java": 70, "JavaScript": 80, "C#": 30 };  
var passed = JSON.stringify(scores, function (key, value) {
       if (value < 40) {
          return undefined;
       } else {
          return value;
       }
});
alert(passed);   // {"Java":70,"JavaScript":80}
Run



Using JSON with AJAX

JSON is frequently used with Ajax. The example below demonstrates a common situation of converting a JavaScript object to JSON, using JSON.stringify(), and then sending it to the server using Ajax. It also demonstrates the reverse of receiving a JSON-formatted response from the server and converting it into a JavaScript object by using JSON.parse().

// Get the browser specific XmlHttpRequest
function createXHRObject() {
    if (window.ActiveXObject) { // IE
       return new ActiveXObject("Microsoft.XMLHTTP");
    }  else if (window.XMLHttpRequest) {
       return new XMLHttpRequest();
    }
}
function getStudentScore() {
    var student = new Student("Kim","Taylor", "JavaScript Training");
    var json = JSON.stringify(student);
    var xmlHttp = createXHRObject();
    // open the connection to the web server with the 
    // XMLHttpRequest object.  score.php is the web server's 
    // page from where we will get the JSON response
    xmlHttp.open("POST", "score.php", true);
    // stores the name of a function to be called 
    // automatically each time the readyState property changes
    xmlHttp.onreadystatechange = handleServerResponse;
    // send the header information along with the request
    xmlHttp.setRequestHeader("Content-type", 
                             "application/x-www-form-urlencoded");
    xmlHttp.setRequestHeader("Content-length", json.length);
    xmlHttp.setRequestHeader("Connection", "close");
    
    // send the JSON-encoded Student object to the server 
    // using the XMLHttpRequest object
    xmlHttp.send(json);
}
function handleServerResponse() {
    // readyState holds the status of the XMLHttpRequest.
    // 4 means the request is finished and response is ready.
    if (xmlHttp.readyState == 4) {
        if (xmlHttp.status == 200) {  // 200 indicates okay
          // Deserializing JSON text into the JavaScript object
          var studentScore = JSON.parse(xmlHttp.responseText);
          // do something with it ...
        }
    }  else if (xmlHttp.status == 400) { // 400 indicates file not found
       //report error
    }
}

As far as the Ajax part is concerned most web sites will use a library such as jQuery and let it handle browser differences. Using jQuery significantly reduces the size of the code as demonstrated below:

function getStudentScore() {
    var student = new Student("Kim","Taylor", "JavaScript Training");
    var json = JSON.stringify(student);
    $.post("score.php", json, function (data) {
        var studentScore = JSON.parse(data);
        // do something with it ...
    }, "json" ); 
}