JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.
JSON is built on two structures:
- A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
- An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangable with programming languages also be based on these structures.
In JSON, they take on these forms:
An object is an unordered set of name/value pairs. An object begins with {(left brace) and ends with }(right brace). Each name is followed by :(colon) and the name/value pairs are separated by ,(comma).
An array is an ordered collection of values. An array begins with [(left bracket) and ends with ](right bracket). Values are separated by ,(comma).
For example:
JSON / XML{
"firstName": "John",
"lastName": "Smith",
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": 10021
},
"phoneNumbers": [
"212 555-1234",
"646 555-4567"
]
} / <firstName>John</firstName>
<lastName>Smith</lastName>
<address>
<streetAddress>
21 2nd Street
</streetAddress>
<city>New York</city>
<state>NY</state>
<postalCode>10021</postalCode>
<address>
<phoneNumbers>
"212 555-1234",
"646 555-4567"
</phoneNumbers>
A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.
A string is a collection of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.
A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.
Whitespace can be inserted between any pair of tokens. Excepting a few encoding details, that completely describes the language.
JSON in JavaScript
JavaScript is a general purpose programming language that was introduced as the page scripting language for Netscape Navigator. It is still widely believed to be a subset of Java, but it is not. It is a Scheme-like language with C-like syntax and soft objects. JavaScript was standardized in the ECMAScript Language Specification, Third Edition.
JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.
var myJSONObject = {"bindings": [
{"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^
{"ircEvent": "PRIVMSG", "method": "deleteURI", "regex": "^delete.*"},
{"ircEvent": "PRIVMSG", "method": "randomURI", "regex": "^random.*"}
]
};
In this example, an object is created containing a single member "bindings", which contains an array containing three objects, each containing "ircEvent", "method", and "regex" members.
Members can be retrieved using dot or subscript operators.
myJSONObject.bindings[0].method // "newURI"
To convert a JSON text into an object, you can use the eval() function. eval() invokes the JavaScript compiler. Since JSON is a proper subset of JavaScript, the compiler will correctly parse the text and produce an object structure. The text must be wrapped in parens to avoid tripping on an ambiguity in JavaScript's syntax.
var myObject = eval('(' + myJSONtext + ')');
The eval function is very fast. However, it can compile and execute any JavaScript program, so there can be security issues. The use of eval is indicated when the source is trusted and competent. It is much safer to use a JSON parser. In web applications over XMLHttpRequest, communication is permitted only to the same origin that provide that page, so it is trusted. But it might not be competent. If the server is not rigorous in its JSON encoding, or if it does not scrupulously validate all of its inputs, then it could deliver invalid JSON text that could be carrying dangerous script. The eval function would execute the script, unleashing its malice.
To defend against this, a JSON parser should be used. A JSON parser will recognize only JSON text, rejecting all scripts. In browsers that provide native JSON support, JSON parsers are also much faster than eval. It is expected that native JSON support will be included in the next ECMAScript standard.
var myObject = JSON.parse(myJSONtext, reviver);
The optional reviver parameter is a function that will be called for every key and value at every level of the final result. Each value will be replaced by the result of the reviver function. This can be used to reform generic objects into instances of pseudoclasses, or to transform date strings into Date objects.
myData = JSON.parse(text, function (key, value) {
var type;
if (value & typeof value === 'object') {
type = value.type;
if (typeof type === 'string' & typeof window[type] === 'function') {
return new (window[type])(value);
}
}
return value;
});
A JSON stringifier goes in the opposite direction, converting JavaScript data structures into JSON text. JSON does not support cyclic data structures, so be careful to not give cyclical structures to the JSON stringifier.
var myJSONText = JSON.stringify(myObject, replacer);
If the stringify method sees an object that contains a toJSON method, it calls that method, and stringifies the value returned. This allows an object to determine its own JSON representation.
The stringifier method can take an optional array of strings. These strings are used to select the properties that will be included in the JSON text.
The stringifier method can take an optional replacer function. It will be called after the toJSON method (if there is one) on each of the values in the structure. It will be passed each key and value as parameters, and this will be bound to object holding the key. The value returned will be stringified.
If you do not provide an array or replacer function, then an optional replacer function will be provided for you that omits inherited properties. If you want all inherited properties, you can provide a simple replacer function:
var myJSONText = JSON.stringify(myObject, function (key, value) {
return value;
});
Values that do not have a representation in JSON (such as functions and undefined) are excluded.
Nonfinite numbers are replaced with null. To substitute other values, you could use a replacer function like this:
function replacer(key, value) {
if (typeof value === 'number' & !isFinite(value)) {
return String(value);
}
return value;
}
Giving a corresponding revivor to JSON.parse can undo that.
Using JSON in Ajax
The following Javascript code shows how the client can use an XMLHttpRequest to request an object in JSON format from the server. (The server-side programming is omitted; it has to be set up to respond to requests at url with a JSON-formatted string.)
var the_object;
var http_request = new XMLHttpRequest();
http_request.open("GET", url, true);
http_request.send(null);
http_request.onreadystatechange = function(){
if( http_request.readyState == 4){
if( http_request.status == 200){
the_object = eval("(" + http_request.responseText + ")");
}else{
alert("There was a problem with the URL.");
}
http_request = null;
}
};
Note that the use of XMLHttpRequest in this example is not cross-browser compatible; syntactic variations are available for Internet Explorer, Opera, Safari, and Mozilla-based browsers. The usefulness of XMLHttpRequest is limited by the same origin policy: the URL replying to the request must reside within the same DNS domain as the server that hosts the page containing the request. Alternatively, the JSONP approach incorporates the use of an encoded callback function passed between the client and server to allow the client to load JSON-encoded data from third-party domains and to notify the caller function upon completion, although this imposes some security risks and additional requirements upon the server.
Browsers can also use iframe elements to asynchronously request JSON data in a cross-browser fashion, or use simple <form action="url_to_cgi_script" target="name_of_hidden_iframe"> submissions. These approaches were prevalent prior to the advent of widespread support for XMLHttpRequest.
Dynamic <script> tags can also be used to transport JSON data. With this technique it is possible to get around the same origin policy but it is insecure. JSONRequest has been proposed as a safer alternative.
XML
XML is often used to describe structured data and to serialize objects. Various XML-based protocols exist to represent the same kind of data structures as JSON for the same kind of data interchange purposes. But because they use XML, which is a general purpose markup language, they are arguably more complex than JSON, which represents data structures in simple text in a form specifically designed for data interchange (but in an uncompressed format) . Both lack a rich (i.e., explicit) mechanism for representing large binary data types such as image data (although binary data can be serialized for both by applying a general purpose binary-to-text encoding scheme).
JSON / 1