Different methods are currently available to persist user-specific application data in the browser: HTML5 localStorage, HTML5 sessionStorage, cookies, web SQL databases, indexedDBs, and the window.name property. The ideal method to store massive data on the client side that persists beyond page refreshes, sessions, and browser restarts is via the localStorage object, provided by the HTML5 web storage API. The localStorage object is accessed and handled via javascript using pre-defined properties and can also be modified using browser debugging tools.
Problem - Client-Side Data Storage
When working with a considerable amount of client-side data that needs to be sent to the application server, there is always a possibility of internet disconnection. In such scenarios, when the data is important and has been collected as a result of user interaction and responses, the most logical way to prevent its loss is to store ‘state’ of the application i.e. save the huge amount of data on the client-side and then attempt to re-post it to the server again.
Solutions
Although the following different ways of saving application data on the client’s machine exist, each method has its own shortcomings:
Cookies: Cookies are text strings that can be assigned expiry dates to enable them to persist after page refreshes, browser restarts, and system reboots. Cookies are sent between the client and the server in the HTTP header so the user stays logged into a web application between pages. However, cookies can be disabled or blocked by users due to privacy concerns. Each cookie can only retain 4KB of data and generally speaking, a browser allows 20 cookies. Moreover, as cookie data is sent with each HTTP request and returned with each response, it results in additional network traffic.
Web SQL Database: The web SQL database was an attempt to use relational database technologies in the browser to store data. To use this feature, a database must be created by initializing openDatabase method. This method of data storage is not supported by Firefox and IE and was abandoned by the W3C in 2010 so it is better avoided.
IndexedDB: This provides a structured, transactional, high-performance NoSQL-like data store with a synchronous and asynchronous API. IndexedDB is fairly new but it is supported in IE10+, Firefox 23+, Chrome 28+ and Opera 16+. The downsides: IndexedDB is fairly complex and not available in older or mobile browsers.
SessionStorage: The sessionStorage is a web storage API that uses key value pairs to store data. However, sessionStorage data only exists as long as the session exists; closing the tab in which the application is running or exiting the browser lead to loss of saved data.
window.name Property: Although not designed for data storage, the window.name property of every browser can be used to store several megabytes of data. This data, however, can be analyzed and modified by another web application so this browser property is not ideal for storage of sensitive data.When the tab or window in which the property value was set is closed, the data is lost.
HTML5 Local Storage
Given the limitations of the above mentioned methods of persisting data on the client-side, the HTML localStorage web API appears to be the best option for large client-side data storage due to the following reasons:
The HTML localStorage stores domain-specific data in the form of a string of key value pairs that can neither be read by another domain nor modified or cleared unless done so manually.
HTML localStorage allows storage of up to 5MB of data which is far larger than that allowed by a cookie.
Once created, localStorage objects do not need to be transmitted with each HTTP request and response until required.
Browser support is actually pretty good: Chrome 4+; Firefox 3.5+; IE8+; Opera 10.5+; Safari 4+; plus iPhone 2.0+; and Android 2.0+.
HTML5 LocalStorage can be accessed by the web application using javascript. In order to determine whether localStorage is supported by your current browser or not, you can type any one of the following in the browser console and it should return true indicating support for localStorage:
"localStorage" in window && window["localStorage"] !== null;
!(typeof window.localStorage == "undefined");
Once browser support is verified, you can store data using any one of the following ways:
localStorage.setItem("name", "value");
localStorage.name = "value";
localStorage["name"] = "value";
Stored data can be retrieved using any one of the following ways:
localStorage.getItem("name");
localStorage.name;
localStorage["name"];
Stored data can be deleted using any one of the following ways:
localStorage.removeItem("name");
delete localStorage.name;
delete localStorage["name"];
All of the stored data can be deleted from localStorage by using:
localStorage.clear();
Of the above methods, calling setItem(), getItem() and removeItem() methods on the localStorage object are the most preferred ways to set, retrieve and delete data.
In order to get the total number of values in the local storage, you can iterate through all of the keys by index, using the following:
for (var i = 0; i < localStorage.length; i++) {
var name = localStorage.key(i);
var value = localStorage.getItem(name);
console.log(name + " is set to " + value);
}
Debugging HTML5 LocalStorage Using Browser Tools
In addition to using the above properties on the localStorage object directly in the browser console, you can also navigate to the Resources tab of the browser’s developer tools using Ctrl+Shift+I or via More Tools ->Developer tools menu in Chrome. In the Resources view, you can double-click on localStorage in the left-side sub-menu and then select the domain URL so that a table listing existing key-value pairs associated with that domain appears.
There are several ways to create, edit and delete HTML5 localStorage key values directly from this table.
To add a new key value pair, first double-click on and enter key in an empty table cell under the key column and then double-click and enter value in the adjacent empty cell in the same row under the value column.
To edit an existing key value pair, again double-click on the cell that you want to modify or right-click and select edit.
To delete a key value pair, select the row you want to delete and then click the cross icon at the bottom of the table. You can also right-click on the data item and select delete.
To refresh the table with new storage data, click the refresh icon at the bottom of the table.
HTML5 LocalStorage Code Example
The following is an example of how localStorage can be used to save and retrieve data in an application.
Step 1: A massive amount of data is collected by a web application via interactions with the user and it needs to be transmitted to the remote server. It must be stored locally to prevent data loss in case the internet connection is disrupted.
if(typeof(Storage) !== "undefined") {
localStorage.setItem("resultsObject", userData)
}
Step 2: If the internet gets disconnected during data transfer, the user can choose to revisit the site and resend this data. Upon the user’s subsequent revisit to the site, the application verifies if any key for the results exists for this domain and then presents the user with an option to resend the data via a button click.
window.onload=function()
{
if(localStorage.getItem("resultsObject") !== null)
{
var alertElem = document.getElementById("upload-message")
alertElem.classList.remove("hidden");
var btnElem = document.getElementById("uploadButton")
btnElem.classList.remove("hidden")
}
}
function submitResult()
{
document.getElementById("testResults").innerHTML=
localStorage.getItem("resultsObject");
document.getElementById("testResultsForm").submit();
}
where, the button element is defined as:
and the upload message as:
To upload results to server, click the upload button below.
Step 3: Once the data has been transmitted successfully to the server, the user can be redirected to another page and the localStorage object deleted upon redirection.
window.onload=function()
{
if(localStorage.getItem("resultsObject") !== null)
{
localStorage.removeItem("resultsObject");
}
}
Step 4: You can also include a mechanism to verify if localStorage data is valid before re-transmitting to server. If the user data is corrupted, you must discard it by removing the localStorage item.
function verifyData()
{
var isDataValid = document.getElementById("isDataValid").value;
if(localStorage.getItem("resultsObject") !== null && isDataValid == "false")
{
localStorage.removeItem("resultsObject");
}
}
Comments