A brief overview of JSON
JavaScript Object Notation (JSON) is an open, text-based data exchange format based on JavaScript's object literal notation. Here we learn how to safely convert a JSON string (message) into a JavaScript object and vice versa, then review a customizable webpage example.
Using JSON
The JSON format is often used for serializing and transmitting structured data over a network connection, such as between a server and web application. Be aware, however, that JSON can be used in virtually any scenario where software components need to exchange or store structured information as text.
Consider the following JavaScript JSON formatted string:
'{"firstName":"John","lastName":"Doe","phone":"958-555-0100","age":25}'
This string provides structured, text-based information about a person (John Doe, in this case) and can be safely converted into a JavaScript object by using the JSON
object's parse method:
var person = JSON.parse('{"firstName":"John","lastName":"Doe","phone":"958-555-0100","age":25}');
Important The eval method can be used perform the same JSON.parse operation. Whenever possible, use JSON.parse to de-serialize JSON text. The JSON.parse function is more secure and executes faster than the eval function.
After the JSON string has been converted into a JavaScript object, the age
of person
simply becomes person.age
:
alert("The value of the 'age' property for the 'person' object is: " + person.age);
Using JSON.stringify, the inverse is just as simple:
var JavaScriptObjectLiteral = {
firstName: "John",
lastName: "Doe",
age: 25
}
alert( JSON.stringify(JavaScriptObjectLiteral) );
In other words, given a JavaScript object, JSON.stringify returns the equivalent JSON formatted string. This can be quite handy, as shown in the following example.
A customizable webpage
Consider a website where a user has the option of locally "logging" into the site. This local login information (or "credentials") could be used for a myriad of purposes including allowing the user to customize the site to their liking. For example, the user could supply a name and an optional password for a particular client-side customization. For pedagogical reasons, the only allowed customization is a change of background color. This core idea, however, can be extended to much more complex customization scenarios.
Before examining the following example, be aware that the window.localStorage
object is generally only available when the page is served from a webserver. Thus, locally saving and viewing (running) the following example might not work as expected. Instead, view the example from a live webserver: JSON - A Breif Overview. A screen shot of JSON - A Breif Overview follows.
Note Before proceeding, review the code shown in the previous image. To do so, navigate to JSON - A Breif Overview, right-click the page and choose View source.
The markup section of the code is essentially composed of two forms (<form>
), one visible and the other initially hidden. The visible credentialsForm
form collects the user's credentials and calls getCredentials(this.form)
when the Submit button is clicked. Be aware that this.form
passes a form reference to the getCredentials
function:
function getCredentials(credentialsFormObject) {
userToken.user = sanitizeHTML(credentialsFormObject.user.value);
userToken.password = sanitizeHTML(credentialsFormObject.pwd.value);
if ( newUser() ) {
document.getElementById('backgroundColorForm').style.display = "block";
}
else {
setCustomizations();
}
}
The algorithm for getCredentials
is straightforward:
- Place the sanitized user credentials into the global variable
userToken
(so that this information can be accessed easily by other functions). - Call
newUser
to determine if the user's credentials indicates that this is a new user. If so, display thebackgroundColorForm
form. Otherwise, set the background color to the user's previously saved color preference by callingsetCustomizations
.
The code for newUser
is as follows:
function newUser() {
var JSON_userTokens = window.localStorage.userTokens;
if (!JSON_userTokens) {
return true;
}
var userTokens = JSON.parse(JSON_userTokens);
for (var i = 0; i < userTokens.length; i++) {
if (userTokens[i].user == userToken.user && userTokens[i].password == userToken.password) {
userToken.backgroundColor = userTokens[i].backgroundColor;
return false; // This user already exists.
}
}
return true;
}
The window.localStorage.userTokens
property returns a (possibly empty) JSON formatted "string array" of user tokens associated with this user's domain and places it in JSON_userTokens
. The "string array" is turned into a true JavaScript array via JSON.parse(JSON_userTokens)
. We then iterate through the elements of the array to determine if userToken
is a known user and if so:
- Save the user's previously saved background color preference to the global
userToken
(for later use bysetCustomizations
). - Return
false
indicating that this is not a new user (but a known user).
If newUser
returns false
, the function setCustomizations
is called (see the if-then
statement of getCredentials
earlier). setCustomizations
assumes that the user indicated via userToken
is known and therefor directly sets the background color of the page to the user's previously saved preference:
function setCustomizations() {
document.getElementsByTagName('body')[0].style.backgroundColor = userToken.backgroundColor;
}
If, on the other hand, newUser
returns true
, only the backgroundColorForm
form is displayed (as shown in this fragment from getCredentials
):
if ( newUser() ) {
document.getElementById('backgroundColorForm').style.display = "block";
}
This results in output similar to the following:
When the new user enters a CSS color string, such as "#543" or "cyan" and the Submit button is clicked, getBackgroundColor(this.form)
is invoked:
function getBackgroundColor(backgroundFormObject) {
userToken.backgroundColor = sanitizeHTML(backgroundFormObject.cssColor.value);
addUser();
setCustomizations();
document.getElementById('backgroundColorForm').style.display = "none";
}
The entered color string is retrieved from the form's input
element (named cssColor
) and stored in the global userToken
. Next, the addUser
function is called:
function addUser() {
var userTokens = [];
var JSON_userTokens = window.localStorage.userTokens;
if (JSON_userTokens) {
userTokens = JSON.parse(JSON_userTokens);
}
userTokens.push(userToken);
window.localStorage.userTokens = JSON.stringify(userTokens);
}
This adds the new user's information (userToken
) to persistent local storage. The JSON.stringify
and JSON.parse
conversions are necessary in that Web Storage can only store string key/value pairs.
Finally, setCustomizations
is called to set the background color to the just obtained user's preference, and the backgroundColorForm
form is re-hidden.
Flexibility of web storage and JSON
Because Web Storage only allows strings (in the form of key/value pairs), JSON can be used to convert complex JavaScript objects into easily storable JSON strings and vice versa. Since allowed Web Storage allocations are much larger (megabytes) than typical cookie storage allocations (kilobytes), Web Storage in conjunction with JSON can provide a number of interesting scenarios including local user website customization, as outlined in the preceding example.