As we know, localStorage and sessionStorage have came up for years. They're commonly used in front-end cache for both online and offline situations, like, storing JWT.
I suppose you have been way familar with them already, so here's just a quick note for myself. If it's also your jam, stay tuned!
Why we need additional storage objects besides cookies?
Although cookie is capable of storing in client-side, but there are some downsides where the web storage objects have value of.
- Unlike cookies, web storage objects will not be sent along with every single request. There is no much extra workload, even if we store dozens of data by web storage objects.
- Most browsers allow at least two megabytes or more (have to configure by user themselves) for web storage objects, so we could have better performance by cache more.
- The data stored in web storage object can survive from page refresh and even a full browser or OS restart.
The same APIs for both web storage objects
LocalStorage and sessionStorage both land as the immediate property of global object(that's, window), and provide the same APIs for us.
setItem(key: string, value: any): void
store a key/value pair.getItem(key: string): string
get value by key.removeItem(key: string): void
remove a key with its value.clear(): void
delete everything.key(index: number): string
get the key on given position.length: number
get the amount of key/value pairs.
The most important thing to note is that, the value passed into setItem
method would be converted to a string automatically before store, that means it will call the toString
method of the given value first, and then save the returned value finally. If you want to put an object in, call JSON.stringify
first, and then execute JSON.parse
when get it back.
And it's possible to stringify the whole storage object, e.g. for debugging purposes:
// add formatting options to JSON.stringify to make the object look prettier.
JSON.stringify(localStorage, null, 2)
What's the difference between them?
The ability for cross-context communication:
- SessionStorage is scoped on per-window basis, that means multiple browser tabs with documents on the same origin have a separated sessionStorage, but iframes on the same origin within the same window/tab can share the sessionStorage.
- LocalStorage can be shared between all browsing-contexts(iframe, window and tabs) and workers.
The expiration machinsm:
- Data stored in sessionStorage will expire automatically when close the browser tab.
- Data persisted in localStrorage will live as long as it could until user perform data clearence.
Detecting changes by StorageEvent
We can detect all changes(adds, updates and deletes) on both localStorage and sessionStorage.
Here's the properties of StorageEvent
:
key
the key that was changed,null
ifclear()
is called.oldValue
the old value,null
if the key is newly added.newValue
the new value,null
if the key is deleted.url
the url of the ducument where the change happend.storageArea
eitherlocalStorage
orsessionStorage
object where the change occured.
There is a pitfall when listening changes on localStorage, that's event handler will not be called when the change is performed in the same browsing-context, for instance like below:
// a.html
window.addEventListener('storage', evt => {
console.log('a:', evt.key)
})
setTimeout(()=> {
localStorage.setItem('a', 1)
}, 5000)
// b.html
window.addEventListener('storage', evt => {
console.log('b:', evt.key)
})
setTimeout(()=> {
localStorage.setItem('b', 1)
}, 10000)
Console for a.html will show a:b
after ten seconds, and that of b.html will echo b:a
in five seconds.