# Web Storage

## Summary


Client-server interactions on the web are stateless. This means that a client request is independent of all previous requests. However, many applications require state to be maintained across requests. Examples are shopping on e-commerce sites or filling a form after login authentication. HTTP cookies sent with every request allow us to maintain state. Moreover, server may store session data, often in a database. 

Web Storage is a client-side feature that allows web apps to store data or state on the client/browser without involving the server. Unlike HTTP cookies, storage is managed at the JavaScript layer.

Each web storage area is bound to an origin, which is a triplet of domain, protocol and port. Thus, one domain can't access the storage of another. 

Web Storage shouldn't be confused with cloud storage, which is about storing data on cloud computing platforms.

## Discussion

### Why should I use Web Storage when I can use cookies instead?

Cookies have been used to create client-side state but it has it's limitations. Cookies can be created only on the server and then exchanged with the client. Client must include the cookies with every request to the server. The amount of cookie storage is limited to 4KB. Cookies also are not persistent. They have an expiry time. 

W3C Recommendation for Web Storage notes an example in which a user could have the same site open in two windows. With a cookie implementation, the cookie would "leak" from one window to the other, with the user ending up with duplicate flight bookings. 

With web storage, data can be stored on the client without any support from the server. This is useful for building Single Page Applications (SPAs). Unlike cookies, few megabytes can be stored. Two different types of storage areas are available: local and session. With the former, storage is persistent even if the browser is closed and reopened. 

Some browsers allow 10MB of web storage per origin while others allow 5MB. 


### In Web Storage, how is browser local storage different from session storage?

Local storage has no expiry. Even if the browser is closed, the data will persist. Session storage is limited to the current tab. It will be lost when the tab is closed. 

With session storage on an e-commerce site, it's not possible to accidentally make double purchases just because the same site is open on two different tabs. Using local storage for this use case is not a good idea since the storage is accessible to all tabs opened to that site. 


### Could you share real-world examples of sites using Web Storage?

By 2011, many websites had started to use web storage. A Twitter search tool called Snapbird used it to remember the last person's Twitter stream that the user had searched from that browser. The assumption is that user is likely to continue the same search at a later time, thus saving some effort in retyping the name. Webbie Madness and CSS Lint are two other examples that use local storage to remember user's selection of checkboxes. 

Web storage is not used to store sensitive content such as passwords, JSON Web Tokens or credit card information. However, one developer used it to store the hashed ID of an authenticated user. This hash is later used to give access to protected pages. For example, it can be used to maintain a shopping cart for an e-commerce site. 

In social websites, relying on the server for data can involve complex technologies such server-side caching, distributed databases and DNS load balancers. Instead, web storage can be used to locally store recent chat messages, system notifications and news feeds. 


### What are the basics of managing Web Storage?

The API for using web storage is simple. No libraries need to be installed. Web storage can be used with plain JavaScript code. The storage is just key-value pairs with values being only strings. In case more complex data types need to be stored, such as JavaScript objects or arrays, they need to be serialized into strings. 

To store `username` for example, we can use the syntax `localStorage.username = 'jsmith'` or `localStorage.setItem('username', 'jsmith')`. To retrieve data, use `localStorage.getItem('username')`. Use `localStorage.length` to know how many items are stored. A key can be accessed by its integer position `n` by calling `localStorage.key(n)`. To delete a key-value pair, call `localStorage.removeItem('username')`. Call `localStorage.clear()` to delete all pairs. 

The syntax described above for `localStorage` is also applicable for `sessionStorage`. 

When either local or session storage is modified, `storage` event is fired. The event will contain key, old value and new value.  

An app will fail if it depends on web storage but not supported in a particular browser. The solution is to reliably ascertain browser support and have fallback code. 


### What are some common criticisms of Web Storage?

Web Storage is limited to storing strings. Although more complex data types can be serialized and stored as strings, this is seen as an "ugly hack". In terms of size, few megabytes may not be enough for data-intensive apps or apps that need to work offline. Moreover, it's not easy to know when storage is at its limit. 

Providing app functionality that's highly dependent on web storage can be problematic. Users might delete the data just as they tend to clear cookies.  

The API is synchronous, which implies data loading can block rendering on the main thread. This would be worse if files and images are stored. Likewise, for background processing, web workers can't be used since they can't access web storage. 

Web Storage has security issues. Any JavaScript code on that page can access the storage. Cross-site scripting attacks are possible. Malicious JavaScript code can read the storage and send it to another domain of its choice. This is unlikely if the entire code was built in-house. However, it's common for apps to use third-party code, which could have been compromised.


### Could you share some resources for working with Web Storage?

Beginners can look at a demo of Web Storage as well as details of the storage event that's triggered by each change to the storage.

There are wrappers around Web Storage. *Lockr* allows developers to store non-string values as well. *Store.js* is similar to Lockr but with fallback should the browser lack support for web storage. *Crypt.io* (previously called secStore.js) adds a security layer. *Barn* provides a Redis-like interface. For asynchronous calls, *localForage* combines the easy-to-use Web Storage API with IndexedDB. A quick search on NPM will reveal many more packages related to local storage.

PersistJS is a cross-browser alternative to client-side storage.

If your app uses web storage, it's easy to unit test your app even without access to browser's web storage. Web Storage can be *mocked* and one developer shows how to do this in Angular. 


### Which are the alternatives to Web Storage?

For sensitive data such as a session ID, it's better to use signed cookies. When using cookies, use the `httpOnly` cookie flag and set `SameSite=strict` and `secure=true`. For most other sensitive data, use server-side storage. 

For non-string and non-sensitive data, use IndexedDB. This gives standard database features including primary keys, indexing, and transactions. For offline applications, we could use a combination of IndexedDB and Cache API that's often used by service workers. In fact, it's possible to create a polyfill to override default Web Storage API to store in IndexedDB and store asynchronously. 

Web SQL used to be an alternative but W3C stopped working on this due to lack of implementations. 

Application Cache is a text file to tell browsers what resources to cache. This could be useful for offline viewing of the site. It's more of a caching mechanism than client-side storage. 

## Milestones

Apr  
2009

W3C releases the first working draft of **Web Storage**. This draft defines both `localStorage` and `sessionStorage`. In addition, it defines an interface to store in databases. 

Jun  
2013

W3C publishes **Web Storage** as a W3C Recommendation. Database storage defined in the first draft is deleted in the Recommendation. Both `localStorage` and `sessionStorage` are referred to as *IDL attributes*, following Web IDL (Interface Definition Language) that's used to describe interfaces web browsers are required to implement. The Recommendation also points out issues of user privacy and sensitive data, and how user agents (browsers) can mitigate the risks. 

Apr  
2016

W3C publishes **Web Storage (Second Edition)** as a W3C Recommendation. 

Apr  
2019

Web storage is slow due to its synchronous nature. On the other hand, IndexedDB is asynchronous but has a more complex API. As a compromise, **KV Storage** is proposed. It's a key-value storage like web storage but with IndexedDB as the underlying storage. It becomes available with the release of Chrome 74 on an experimental basis. The trial ends with Chrome 76. In future, IndexedDB may come with a simpler API.