HTML5 Web Storage Explained

25 aug. 2022
Intermediate
5,27K Views
14 min read  

Prior to HTML5, HTTP cookies were used initially to store information over the browser, e.g. – token value, license info, number of items added in the shopping cart, etc. The storage limit used to be pretty less, 4kb to be precise. These cookies were sent to the server with every request. With the advent of HTML5, there’s been the introduction of the Web Storage API, which helps us to store relevant data in key/value pairs over the browser, with increased storage limit, which is only available at the client end. Well,

The information stored into the web storage may not be sent to the webserver and in the same way, the cookies are completely opposite storage where data is sent to the server with every request. Also, where cookies let us store a small amount of data that can be nearly around 4 MB of data depending upon the browser, the web storage allows us to store up to 10 MB of data respectively.

This was the introduction to start with; let’s dive into the nitty gritty of the Web Storage API.

Web Storage

There are 2 mechanisms within Web Storage.

  1. sessionStorage: The session storage is using the sessionStorage object to store the data on a temporary basis into the browser storage space, specifically for a single active browser window or a tab. The data with being trashed when the active session ends and it happens when the user closes that existing browser window or a tab.

  2. localStorage: The local storage is using the localStorage object to store the data for our entire website on a permanent basis provided that the data should be limited to the specified space for the specific browser compatibility. That means the stored local data will be available on the next day, the next week, or the next year until the specified date/time or the duration will come to an end.

These 2 terms are pretty popular nowadays; you would have heard them as buzzwords around you. With the increased popularity of JavaScript, these two mechanisms are being used extensively. Let’s have a look as to where we can see these 2 storages. If we open the developer console in any of the supporting browsers, we can see that there are this 2 storage.

CHROME

FIREFOX

EDGE

The placement of the storage mechanisms is different in different browsers, which can be viewed pretty easily. One thing to note is that both these mechanisms store data in key/value pairs. There’s been the introduction of 2 new properties in the window object, which helps in the implementation of local and session storage. Let’s have a look in detail:

Window.localStorage

The data stored in the localStorage object never expires, even if the browser is closed. The data can be cleared via code for sure. Let’s see an example of how to use localStorage.

HTML
 <!DOCTYPE html> 
 <html> 
 <head> 
 <meta charset="utf-8" /> 
 <title>HTML5 Web Storage</title> 
 </head> 
 <body> 
 <h1></h1> 
 <script src="storage.js"></script> 
 </body> 
 </html>
JS Code
 if (typeof Storage !== "undefined") { 
 localStorage.setItem("word", "Hello World!!"); 
 } else { 
 alert("The browser doesn't support web storage"); 
 } 
 document.getElementsByTagName('h1')[0].innerHTML = localStorage.getItem("word");

In the above example, we have a very trivial HTML document, with a single <h1> tag, the JavaScript code first checks whether the browser supports the Web Storage API or not, if yes, then the localStorage object gets initialized by setting a key/value pair.

The value of local storage can be set through localStorage.setItem() by specifying the name of the key along with the value, and it can be retrieved through localStorage.getItem() by providing the key name as simple as that.

key: “word”, value: “Hello World!!” in the above example.

Below is the definition of the Web Storage API
 interface Storage { 
 /** 
 * Returns the number of key/value pairs currently present in the list associated with the 
 * object. 
 */ 
 readonly length: number; 
 /** 
 * Empties the list associated with the object of all key/value pairs, if there are any. 
 */ 
 clear(): void; 
 /** 
 * value = storage[key] 
 */ 
 getItem(key: string): string | null; 
 /** 
 * Returns the name of the nth key in the list, or null if n is greater 
 * than or equal to the number of key/value pairs in the object. 
 */ 
 key(index: number): string | null; 
 /** 
 * delete storage[key] 
 */ 
 removeItem(key: string): void; 
 /** 
 * storage[key] = value 
 */ 
 setItem(key: string, value: string): void; 
 }

Let’s validate the point, wherein we have said that the localStorage doesn’t have an expiration time, it’s always stored on the browser.

 if (typeof Storage !== "undefined") { 
 if (localStorage.getItem("word") === null) { 
 localStorage.setItem("word", "Hello World!!"); 
 } 
 else { 
 console.log('Data in localStorage persists'); 
 } 
 } else { 
 alert("The browser doesn't support web storage"); 
 } 
 document.getElementsByTagName('h1')[0].innerHTML = localStorage.getItem("word"); 

Let’s run the above code in which we have checked whether the key ‘word’ has value or not, if yes then set the localStorage item, if not then log information in the console.

localStorage.removeItem(key) removes a certain key/value pair, while localStorage.clear() removes every key/value pairs. Let’s remove and clear localStorage items.

HTML
 <!DOCTYPE html> 
 <html> 
 <head> 
 <meta charset="utf-8" /> 
 <title>HTML5 Web Storage</title> 
 </head> 
 <body> 
 <h1></h1> 
 <div> 
 <img id="image1" width="300px" height="300px" /> 
 <img id="image2" width="300px" height="300px" /> 
 </div> 
 <script src="storage.js"></script> 
 </body> 
 </html>
JS
 if (typeof Storage !== "undefined") { 
 localStorage.setItem('src1', '/Images/feathers.jpg'); 
 localStorage.setItem('src2', '/Images/petals.jpg'); 
 } else { 
 alert("The browser doesn't support web storage"); 
 } 
 document.getElementById('image1').src = localStorage.getItem('src1'); 
 document.getElementById('image2').src = localStorage.getItem('src2'); 

Let’s remove one item

 localStorage.removeItem('src1'); 

Let’s clear the localStorage totally -

 localStorage.clear();

Window.sessionStorage

sessionStorage stores the data in the same key/value pair format as localStorage does, with the exception that data in sessionStorage gets lost when the session gets over, i.e. when the browser tab is closed. Let’s have a look at sessionStorage in detail.

JS
 if (typeof Storage !== "undefined") { 
 sessionStorage.setItem('src1', '/Images/feathers.jpg'); 
 sessionStorage.setItem('src2', '/Images/petals.jpg'); 
 } else { 
 alert("The browser doesn't support web storage."); 
 } 
 document.getElementById('image1').src = sessionStorage.getItem('src1'); 
 document.getElementById('image2').src = sessionStorage.getItem('src2'); 

If we close the browser tab, the sessionStorage items will be empty.

 if (typeof Storage !== "undefined") { 
 if (sessionStorage.getItem('src1') === null && sessionStorage.getItem('src2') === null) { 
 console.log('session storage items are empty'); 
 } 
 } else { 
 alert("The browser doesn't support web storage."); 
 } 

One thing to notice is that key and value both are stored as strings in the web storage; hence it’s the developers’ job to retrieve and typecast the values into their respective data types if required. Let’s see a comparison of HTTP cookies, localStorage, and sessionStorage in a tabular format:

Parameters
Cookies
localStorage
sessionStorage
Size
4 kB
10 MB
10 MB
Expiration
Manually set
Never
On Browser Close
Storage
Browser & Server
Browser
Browser
Sent with Requests
Yes
No
No

Tracking Storage Changes

The Web Storage API provides us with a ‘storage’ event which is fired when there’s a change to the Storage object. This event will not be fired for sessionStorage because the event involves multiple window objects, i.e. this event wouldn’t work on the same page. Let’s see an example.

Page 1 – HTML

 
 <!DOCTYPE html> 
 <html> 
 <head> 
 <meta charset="utf-8" /> 
 <title>Page 1</title> 
 </head> 
 <body> 
 <h1>Page 1</h1> 
 <script> 
 localStorage.setItem('flag', true); 
 
 window.addEventListener('storage', function (e) { 
 console.log(e); 
 console.log(e.key); 
 console.log(e.oldValue); 
 console.log(e.newValue); 
 }); 
 </script> 
 </body> 
 </html> 

The output of the above HTML code is as above in the snapshot, there’s nothing in the console, although we have written a bunch of code in the storage event of the window object, which doesn’t get fired. Let’s add another HTML page.

 <!DOCTYPE html> 
 <html> 
 <head> 
 <meta charset="utf-8" /> 
 <title>2nd page</title> 
 </head> 
 <body> 
 <h1>Page 2</h1> 
 <script> 
 localStorage.setItem('flag', false); 
 </script> 
 </body> 
 </html> 

Let’s open the second page in the browser.

Once we open the second page, the storage event of the first page gets fired and we can see a bunch of values in the first page’s console.

 window.addEventListener('storage', function (e) {
 console.log(e);
 console.log(e.key);
 console.log(e.oldValue);
 console.log(e.newValue);
 });

e.key – key of the localStorage item which has been changed

e.oldValue – the old value of the key

e.newValue – new value of the key which was entered

The storage event has the below-mentioned attributes:

 interface StorageEvent extends Event {
 /**
 * Returns the key of the storage item being changed.
 */
 readonly key: string | null;
 /**
 * Returns the new value of the key of the storage item whose value is being changed.
 */
 readonly newValue: string | null;
 /**
 * Returns the old value of the key of the storage item whose value is being changed.
 */
 readonly oldValue: string | null;
 /**
 * Returns the Storage object that was affected.
 */
 readonly storageArea: Storage | null;
 /**
 * Returns the URL of the document whose storage item changed.
 */
 readonly url: string;
 }

Let’s discuss database storage in the browser. Most modern browsers support Indexed DB, an inbuilt database management system to store more data on browsers themselves, rather than to make a trip to the server. These are much more advanced than the web storage mechanisms, i.e. these help to create indexes on the records as well. Let’s have a look at the key characteristics of the Indexed DB.

  1. Data is stored in key/value pairs.

  2. Operations on Indexed DB are asynchronous in nature.

  3. Transactional support

  4. Large storage space

  5. Supports binary storage

Let’s create a new instance of Indexed DB and see how it works.

 <!DOCTYPE html> 
 <html> 
 <head> 
 <meta charset="utf-8" /> 
 <title>2nd page</title> 
 </head> 
 <body> 
 <h1>Page 2</h1> 
 <script> 
 var request = window.indexedDB.open("sampleDatabase", 2); 
 request.onsuccess = function (result) { 
 console.log(result); 
 console.log(result.target.result.name); 
 }; 
 request.onerror = function (error) { 
 console.log(error); 
 }; 
 </script> 
 </body> 
 </html> 
 var request = window.indexedDB.open("sampleDatabase", 2);

The above line of code will create a new Indexed DB namely ‘sampleDatabase’ with the version number as 2. If the database exists, then this line of code will open that database. The version number is 1 by default. Let’s create a table inside our sampleDatabase

 <script> 
 var request = window.indexedDB.open("sampleDatabase", 2); 
 var db; 
 request.onsuccess = function (result) { 
 console.log(result); 
 console.log(result.target.result.name); 
 }; 
 request.onerror = function (error) { 
 console.log(error); 
 }; 
 request.onupgradeneeded = function (event) { 
 console.log(event); 
 db = event.target.result; 
 var objectStore = db.createObjectStore('sample', { keyPath: 'id' }); 
 }; 
 </script>

onupgradeneeded event is fired when the supplied version number is greater than the actual version number. And we create our table for that very event.

 var objectStore = db.createObjectStore('sample', { keyPath: 'id' });

The name of the table in this scenario is ‘sample’ and the ‘id’ column is the primary key.

Let’s enter data in the table.

 function insertData() { 
 var request1 = db.transaction(['sample'], 'readwrite') 
 .objectStore('sample') 
 .add({ id: 1, name: 'developer', city: 'NY', age: 30 }); 
 
 request1.onsuccess = function (event) { 
 console.log('The data has been written successfully'); 
 }; 
 
 request1.onerror = function (event) { 
 console.log('The data has been written failed'); 
 }; 
 }

We need to specify the mode as read-write or read-only as well.

Let’s retrieve the data

 function retrieveData() { 
 var request = db.transaction(['sample']).objectStore('sample').get(1); 
 request.onsuccess = function () { 
 if (request.result) { 
 console.log('Name: ' + request.result.name); 
 console.log('City: ' + request.result.city); 
 console.log('Age: ' + request.result.age); 
 } 
 }; 
 request.onerror = function (event) { 
 console.log(event); 
 }; 
 } 

Similarly, Update and Delete operations can also be performed.

Summary

So, by now, we can start using or exploring the Web Storage features to store user preferences, basic settings, app configuration, temporary user info, active session info, and other such information into the browser itself. We can also do hands-on stuff by creating apps that can be used completely offline and the data stored offline can be sent back to the server as a piece of update whenever the user is online back again.

In this article, we have explored the Web Storage API, how to work with local and session storage. We have also seen how to work with Indexed DB, create a database, tables, and perform basic CRUD operations.

Share Article
About Author
Anurag Sinha (Author and Full Stack Developer)

He is a Full stack developer, and Author. He has more than 8 years of industry expertise on .NET Core, Web API, jQuery, HTML5. He is passionate about learning and sharing new technical stacks.
Learn to Crack Your Technical Interview

Accept cookies & close this