HTML IN-DEPTH
Web Storages in Depth
With web storage, web applications can store data locally within the user’s browser.
Are you a person who just started with HTML/CSS or someone who wants to have an in-depth knowledge of the advanced features of HTML? Then you are in the right place. So grab a cup of coffee and enjoy the second part of our HTML series, HTML Web Storages.
Have you ever wondered how you are being able to save a password in your browser? or how the browser is being able to recognize that you are already logged it? If not, then you should definitely check out where the browser is hiding the data.
Types of Data Storage:
There are different types of Data Storages where the browser is being able to store data. We can analyse them by dividing into a few categories.
Data Model
The model for storing data determines how the data is organized internally in the browser. It also defines the usability and performance metrics along with the cost of storage and retrievals.
- Structured: Data stored in tables with predefined fields. Example: SQL based DBMS(Database Management System). An example of a structured datastore in the browser with is IndexedDB.
- Key/Value: Data stored in key-value format. Example: NoSQL Database, hash tables. In this, the information is stored and retrieved from unstructured data by unique keys. A prominent example of key/value data storage will be Cache API in the browser
- Byte Streams: This simple model stores data as a variable length. In this case, the format of the data is an opaque string ( An identifier is opaque if it provides no information about the thing it identifies other than being a seemingly random string or number) of bytes. The use case of the model is file systems or other hierarchically organized data. An example of the same would be file systems and cloud storage services
Persistence
Data Storage in web browsers can also be analyzed according to the scope over which data is made persistent.
- Session Persistence: In this type of storage the data stays as long as a single web session or browser tab remains active.For example Session Storage API.
- Device Persistence: Data in this type of storage is preserved across sessions and browser tabs/windows, in a particular device. For example Cache API.
- Global Persistence: Data in this category is maintained across sessions and devices. Till now, it is the most robust form of data storage. For example Google Cloud Storage.
Lists of Data Storages
Cookies: Cookies were once used for general client-side storage. While this was legitimate when they were the only way to store data on the client, but it is now recommended to use modern storage APIs. Cookies are sent with every HTTP request, so storing anything more than a small amount of data worsens the web performance. They are synchronous and are not accessible from web workers.
WebSQL: Support has been removed from almost all major browsers and can be replaced with IndexedDB.
Cache: For the network resources, it is necessary to load the app and file-based content using the Cache Storage. It is a system for storing and retrieving network requests and their corresponding responses. The caches only store pairs of HTTP Response
and Response
objects. However, the requests and responses can contain any kind of data that can be transferred over HTTP. A lot, at least a couple of hundred MB, or potentially hundreds of GB data can be stored in the cache.
IndexedDB: It is a low-level asynchronous API for client-side storage of significant amounts of structured data, including files/blobs. This API uses indexes to enable high-performance searches of this data. While Web Storage is useful for storing smaller amounts of data, it is less useful for storing larger amounts of structured data. IndexedDB provides a solution. However, it requires significant set up before use, which can be particularly painful for storing simple data.
Web Storage:
With Web Storage, web applications can store data locally within the browser. Before it, data had to be stored in cookies via every server request. But now Web storage is more secure, and large amounts of data can be stored locally, without affecting website performance. The storage limit is much larger (at least 5MB) and information is never transferred to the server. Web storage is stored per origin (per domain and protocol). So, all pages, from one origin, can store and access the same data.
Types of Web Storage:
There are two different types of Web Storages: localStorage
andsessionStorage
. Before getting into them, let’s explore a little about window object
and StorageEvent
which will provide a better understanding of storage properties.
Window
The Window object
represents a window containing a DOM document. Now the document
property points to the DOM document loaded in that window. A window for a given document can be obtained using the document.defaultView
property. The Web Storage API extends the Window
object with two new properties — Window.sessionStorage
and Window.localStorage
StorageEvent :
The storage
event is fired on a document's Window
object when a storage area changes. These mechanisms are available via the Window.sessionStorage
and Window.localStorage
properties and invoking any one of these will create an instance of the Storage
object, through which data items can be set, retrieved and removed.
The localStorage Object
The localStorage object stores the data with no expiration date. The data will not be deleted when the browser is closed and will be available the next day, week, or year. The data only gets cleared only through JavaScript code or by clearing the Browser cache / Locally Stored Data.
Limit: 2MB to 10MB
// Store Data
localStorage.setItem(“lastname”, “Smith”);// Retrieve Data
localStorage.getItem(“lastname”);// or,
localStorage.lastname;//looping over keys
for(let i=0; i<localStorage.length; i++) {
let key = localStorage.key(i);
alert(`${key}: ${localStorage.getItem(key)}`);
}//removing data
localStorage.removeItem("lastname");//clearing data
localStorage.clear()
localStorage executes every property of normal object like
hasOwnProperty
,Object.keys
etc.
The sessionStorage Object
The sessionStorage
the object is equal to the localStorage object, except that it stores the data for only one session. The data is deleted when the user closes the specific browser tab.
Limit: At most 5MB
// Store data
sessionStorage.setItem(“lastname”, “Smith”);// Retrieve data
sessionStorage.getItem(“lastname”);// or,
sessionStorage.lastname;//remove data
sessionStorage.removeItem("lastname");
List of Storage methods and properties:
setItem(key, value)
– store key/value pair.getItem(key)
– get the value by key.removeItem(key)
– remove the key with its value.clear()
– delete everything.key(index)
– get the key on a given position.length
– the number of stored items.
Example Implementation:
we are taking the example of the localStorage to avoid repeating the concept but please note that the same implementation can also be done for sessionStorage
Checking storage population
To start with, we test whether the storage object has already been populated (i.e., the page was previously accessed or not):
if(!localStorage.getItem('bgcolor')) {
populateStorage();
} else {
setStyles();
}
In the above case, we are testing whether the bgcolor
item exists; if not, we run functionpopulateStorage()
to add/set the customization values to the storage. If there are already values there, we run functionsetStyles()
to update the page styling with the stored values.
Setting values in storage
Storage.setItem()
is used both to create new data items, and (if the data item already exists) update existing values. This takes two arguments: the key of the data item to create/modify, and the value to store in it.
function populateStorage() {
localStorage.setItem('bgcolor',
document.getElementById('bgcolor').value);
}
Getting values from storage
As noted above, values can be retrieved from storage using Storage.getItem()
. This takes the key of the data item as an argument and returns the data value. For example:
function setStyles() {
var currentColor = localStorage.getItem('bgcolor'); document.getElementById('bgcolor').value = currentColor;
htmlElement.style.backgroundColor = '#' + currentColor;
}
Here, we first grab the values from local storage. Next, we set those values, so that they keep in sync when we reload the page. Finally, we update the styles, so that our customization options come up again on reload.
Responding to storage changes with the StorageEvent:
The StorageEvent
is fired whenever changes are made to the Storage object This won’t work on the same page that is making the changes — it is really a way for other pages on the domain using the storage to sync any changes that are made. Pages on other domains can’t access the same storage objects.
Note: This event is not fired for sessionStorage changes.
window.addEventListener(‘storage’, function(e) {
document.querySelector(‘.my-key’).textContent = e.key;
});
Here we add an event listener to the window object that fires when the Storage object associated with the current origin is changed.
List of Storage Properties
When the data gets updated in localStorage
or sessionStorage
, storage event triggers, with properties:
key
– the key that was changed (null
if.clear()
is called).oldValue
– the old value (null
if the key is newly added).newValue
– the new value (null
if the key is removed).url
– the URL of the document where the update happened.storageArea
– eitherlocalStorage
orsessionStorage
object where the update happened.
The important thing is, the event triggers on all window
objects where the storage is accessible, except the one that caused it.
Confused!!!
Experiment:
Open your terminal in the directory containing an HTML file and run a simple HTTP server with python -m SimpleHTTPServer
. The site will be served in localhost:800
by default.
Now open the same site in two different browser tabs. In the first tab, open the console and type localStorage.setItem('test','test of tab1');
In the second tab open the console and type an alert message as alert("window.localStorage.test");
. At that moment only you will see the value set on the second tab as an alert.
Also,
event.storageArea
contains the storage object – the event is the same for bothsessionStorage
andlocalStorage
, soevent.storageArea
references the one that was modified. We may even want to set something back in it, to “respond” to a change.That allows different windows from the same origin to exchange messages.
How much storage is available?
In browsers, we can use the StorageManager to determine the amount of storage available to the origin, and how much storage is being used. It reports the total number of bytes used by IndexedDB and the Cache API and makes it possible to calculate the approximate remaining storage space available.
if (navigator.storage && navigator.storage.estimate) {
const quota = await navigator.storage.estimate();
// quota.usage -> Number of bytes used.
// quota.quota -> Maximum number of bytes available.
const percentageUsed = (quota.usage / quota.quota) * 100;
console.log(`You've used ${percentageUsed}% of the available storage.`);
const remaining = quota.quota - quota.usage;
console.log(`You can write up to ${remaining} more bytes.`);
}
The
StorageManager
isn’t implemented in all browsers yet
Private Browsing/ Incognito Mode
Incognito’, ‘Private Browsing’ or something similar that doesn’t store data like history and cookies. This is fundamentally incompatible with Web Storage for obvious reasons.
Most browsers use a strategy where storage APIs are still available and apparently fully functional but with the one big difference that all stored data is cleared after the browser is closed. For these browsers, there are still different conceptions of what should be done with existing stored data(Should it be available to read when in Private mode). Again there are some browsers, most notably Safari, that have opted for a solution where storage is available, but is empty and has a quota of 0 bytes assigned. This makes it impossible to write data to it.
Browser Support
Code to check for browser support:
if (typeof(Storage) !== “undefined”) {
// Code for localStorage/sessionStorage.
} else {
// Sorry! No Web Storage support..
}//or,
function storageAvailable(type) {
var storage;
try {
storage = window[type];
var x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
}
catch(e) {
return e instanceof DOMException && (
// everything except Firefox
e.code === 22 ||
// Firefox
e.code === 1014 ||
// test name field too, because code might not be present
// everything except Firefox
e.name === 'QuotaExceededError' ||
// Firefox
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
// acknowledge QuotaExceededError only if there's something already stored
(storage && storage.length !== 0);
}
}//by calling
if (storageAvailable('localStorage')) {
// Yippee! We can use localStorage awesomeness
}
else {
// Too bad, no localStorage for us
}
Resources:
So that’s it for this article. I hope you all liked it and if you liked it then do not forget to tell us your thoughts in the comment section below.
If you want to connect with me, here I am at Twitter or Instagram
Follow our community LinkedIn group, Facebook Page and Twitter for more such articles and posts and meet like-minded people to collaborate.