# LocalStorage, sessionStorage Web storage objects `localStorage` and `sessionStorage` allow to save key/value pairs in the browser. What's interesting about them is that the data survives a page refresh (for `sessionStorage`) and even a full browser restart (for `localStorage`). We'll see that very soon. We already have cookies. Why additional objects? - Unlike cookies, web storage objects are not sent to server with each request. Because of that, we can store much more. Most browsers allow at least 2 megabytes of data (or more) and have settings to configure that. - Also unlike cookies, the server can't manipulate storage objects via HTTP headers. Everything's done in JavaScript. - The storage is bound to the origin (domain/protocol/port triplet). That is, different protocols or subdomains infer different storage objects, they can't access data from each other. Both storage objects provide same 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. As you can see, it's like a `Map` collection (`setItem/getItem/removeItem`), but also keeps elements order and allows to access by index with `key(index)`. Let's see how it works. ## localStorage demo The main features of `localStorage` are: - Shared between all tabs and windows from the same origin. - The data does not expire. It remains after the browser restart and even OS reboot. For instance, if you run this code... ```js run localStorage.setItem('test', 1); ``` ...And close/open the browser or just open the same page in a different window, then you can get it like this: ```js run alert( localStorage.getItem('test') ); // 1 ``` We only have to be on the same origin (domain/port/protocol), the url path can be different. The `localStorage` is shared between all windows with the same origin, so if we set the data in one window, the change becomes visible in another one. ## Object-like access We can also use a plain object way of getting/setting keys, like this: ```js run // set key localStorage.test = 2; // get key alert( localStorage.test ); // 2 // remove key delete localStorage.test; ``` That's allowed for historical reasons, and mostly works, but generally not recommended, because: 1. If the key is user-generated, it can be anything, like `length` or `toString`, or another built-in method of `localStorage`. In that case `getItem/setItem` work fine, while object-like access fails: ```js run let key = 'length'; localStorage[key] = 5; // Error, can't assign length ``` 2. There's a `storage` event, it triggers when we modify the data. That event does not happen for object-like access. We'll see that later in this chapter. ## Looping over keys As we've seen, the methods provide "get/set/remove by key" functionality. But how to get all saved values or keys? Unfortunately, storage objects are not iterable. One way is to loop over them as over an array: ```js run for(let i=0; i { if (event.key != 'now') return; alert(event.key + ':' + event.newValue + " at " + event.url); }; localStorage.setItem('now', Date.now()); ``` Please note that the event also contains: `event.url` -- the url of the document where the data was updated. Also, `event.storageArea` contains the storage object -- the event is the same for both `sessionStorage` and `localStorage`, so `event.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.** Modern browsers also support [Broadcast channel API](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API), the special API for same-origin inter-window communication, it's more full featured, but less supported. There are libraries that polyfill that API, based on `localStorage`, that make it available everywhere. ## Summary Web storage objects `localStorage` and `sessionStorage` allow to store key/value in the browser. - Both `key` and `value` must be strings. - The limit is 2mb+, depends on the browser. - They do not expire. - The data is bound to the origin (domain/port/protocol). | `localStorage` | `sessionStorage` | |----------------|------------------| | Shared between all tabs and windows with the same origin | Visible within a browser tab, including iframes from the same origin | | Survives browser restart | Survives page refresh (but not tab close) | API: - `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 number `index`. - `length` -- the number of stored items. - Use `Object.keys` to get all keys. - We access keys as object properties, in that case `storage` event isn't triggered. Storage event: - Triggers on `setItem`, `removeItem`, `clear` calls. - Contains all the data about the operation (`key/oldValue/newValue`), the document `url` and the storage object `storageArea`. - Triggers on all `window` objects that have access to the storage except the one that generated it (within a tab for `sessionStorage`, globally for `localStorage`).