One of the most common uses of asynchronous JavaScript in web development is live page updates: loading new content for a portion of a page, without reloading the page in full. This is made very simple by the thousands of JavaScript examples available on the Web, but there is a deficiency inherent in this methodology.
If you need to update more than one portion of a page at the same time, the traditional asynchronous request can cause some pain. Since the methodology only allows for the update of one portion, multiple requests have to be generated; each of these requests will have a load time, involving processing and transfer. The end result is that the application works less efficiently than otherwise may be possible.
If instead, it were possible to retrieve all the updates in one request, that would allow for a quicker and more responsive application. This can be done relatively simply, by taking advantage of JavaScript Object Notation.
JSON encoding
By way of example, let's take a football results website that wishes to display scores in more-or-less real time. By the traditional method of asynchronous requests, this could be done one of two ways:
- Requesting a full results update: By refreshing the results container in full, more transfer load is generated, especially if the results have not changed between requests.
- Requesting updates for each game: Since the client cannot know which games have had changed results, every game must be updated. This generates even more transfer and processing load than the first option.
A good way to alleviate this problem would be to send only the games which have changed score, in some easy-to-transfer encoding. JSON provides that encoding, through a few simple rules:
- A value can be a number, string,
true
,false
,null
, or one of the following two types. - An array is a series of values, indexed sequentially from zero; values can be of any type, including another array.
- An object is a set of name/value pairs, where the name is a string and the value can be any type, including another object.
If the current list of football results is as follows:
HTML for multiple-score results page
<ul><li>Manchester United:<strongid="MAN">2</strong>-<strongid="AST">3</strong>:Aston Villa</li><li>Arsenal:<strongid="ARS">1</strong>-<strongid="EVE">1</strong>:Everton</li></ul>
A simplistic method of transferring some updates for the football results may, using JSON, generate the following response:
JSON-encoded multiple-score update
{"MAN":3, "EVE":2}
As can be seen in the above response, the value for MAN
is now
3, and the value for EVE
is 2. These name/value pairs can be used
to update the appropriate elements: for each pair in the response, update the
element whose id
is the name of the pair, with the new value.
Handling JSON responses
The name "JavaScript Object Notation" infers some native ability of JavaScript to understand it; and indeed, it's possible for a script to simply evaluate the JSON response and refer to its contents as if it were a normal variable. A script to update the page contents in the manner described above may look similar to this:
Decoding and performing a multiple-score update
updateScores = function(response) { r = eval('(' + response + ')'); for (k in r) document.getElementById(k).innerHTML = r[k]; };
If this function is used as the response handler by the AJAX script, it will be able to parse the JSON-encoded strings returned from the server. One of the advantages of using JSON is the ability to send other things than a plain response; for example, an inline script could be sent with the update:
JSON-encoded update with inline JS
{"MAN":3, "EVE":2, "script":"alert('There has been an update.');"}
A simple modification to the response handler will suffice to be able to use this new inline script:
Decoding a JSON update with a script
updateScores = function(response) { r = eval('(' + response + ')'); for (k in r) { if(k == 'script') eval(r[k]); else document.getElementById(k).innerHTML = r[k]; } };
There are a couple of caveats involved with using this methodology:
- Quoting:
- The JSON standard dictates that strings must be enclosed in double-quotes; this means that any double-quotes in the string contents have to be escaped if JavaScript is to understand them. This should automatically be handled by the server script's JSON encoding mechanism, but it's something that the encoder may trip up on.
- Security:
- Many developers refuse to conscience the use of
eval
in JavaScript, since it's possible for arbitrary code to be executed simply by returning desired code instead of the JSON response. Some precautions have been taken by the response handler I've set out above, but the server should also be employed to ensure that the requesting session is valid.
If these issues are kept in mind, JSON-encoded AJAX responses are a very useful tool for live Website updates, and can be built upon to generate highly efficient and responsive tools.