Подробнее об объекте Storage https://developer.mozilla.org
Объекты веб-хранилища localStorage и sessionStorage имеют объем 2 Мб+ (зависит от браузера) и позволяют хранить пары ключ-значение в браузере, при этом данные, которые в них записаны, сохраняются:
- течение сеанса, до закрытия браузера - при хранении в sessionStorage ;
- даже после перезапуска браузера - при хранении в localStorage (удаляются с помощью JavaScript).
Ключи и значения всегда имеют тип string (так же как и объекты, целочисленные ключи автоматически будут преобразованы в строки).
Поэтому для хранения объектов можно использовать JSON, например:
1 2 3 4 5 6 |
// сохраним объект sessionStorage.user = JSON.stringify({ name: "Alex" }); // получим значение let user = JSON.parse(sessionStorage.user); alert(user.name); // Alex |
Также возможно привести к строке весь объект хранилища, например для отладки:
1 |
JSON.stringify(localStorage, null, 2); |
Отличие объектов веб-хранилищ от куки:
- объекты веб-хранилища не отправляются на сервер при каждом запросе, что позволяет хранить больше данных;
- сервер не может манипулировать объектами хранилища через HTTP-заголовки;
- хранилище привязано к источнику (домен/протокол/порт): разные протоколы или поддомены определяют разные объекты хранилища, и они не могут получить доступ к данным друг друга.
Методы объектов хранилища localStorage и sessionStorage:
- localStorage.setItem(key, value) – сохранить пару ключ/значение;
- localStorage.getItem(key) – получить данные по ключу key;
- localStorage.removeItem(key) – удалить данные с ключом key;
- localStorage.key(n) – получить именование n-ного ключа в Storage;
- localStorage.clear() – удалить всё.
Пример:
1 2 3 4 5 6 7 8 9 |
localStorage.setItem("myKey", "myValue"); localStorage.setItem("my_Key", "my_Value"); // получаем данные let lclStrg = localStorage.getItem("myKey"); // myValue let lcl_Strg = localStorage.getItem("my_Key"); // my_Value // удаляем элемент lcl_Strg = localStorage.removeItem("my_Key"); // undefined // очищаем localStorage localStorage.clear(); |
Когда обновляются данные в localStorage или sessionStorage, генерируется событие storage.
Хранилище localStorage
Основные особенности localStorage:
- Этот объект один на все вкладки и окна в рамках источника (один и тот же домен/протокол/порт).
- Данные не имеют срока давности, по которому истекают и удаляются.
- Данные cохраняются после перезапуска браузера и операционной системы.
- Этот объект доступен всем окнам из одного источника (данные, установленные в одном окне, становятся видимыми в другом).
Можно получать и записывать данные как в обычный объект, без использования методов localStorage.setItem(key, value), localStorage.getItem(key):
1 2 3 4 5 6 7 8 |
// установить значение для ключа localStorage.myKey = 2; // получить значение по ключу console.log(localStorage.myKey); // 2 // удалить ключ delete localStorage.myKey; |
Однако, обычно этот подход не рекомендуется по следующим причинам:
- Если ключ генерируется пользователем, то он может быть каким угодно, включая именование встроенных свойств или методов localStorage, например, length или toString ). В этом случае методы getItem() и setItem() отработают нормально, а вот чтение (запись) данных как свойство обычного объекта не пройдут (выдаст ошибку).
- При обращении к несуществующему свойству с помощью метода getItem() получим значение null, а если обратиться как к свойству обычного объекта - получим undefined (что при дальнейшей обработке при приведении типов может выдать ошибку).
Перебор ключей localStorage
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
// localStorage.length - количество ключей в хранилище for (let i = 0 ; i < localStorage.length; i++) { const key = localStorage.key(i); // получим ключ с помощью метода key() console.log(`${key}: ${localStorage.getItem(key)}`); } // или for (let key in localStorage) { if (!localStorage.hasOwnProperty(key)) { continue; // пропустит встроенные ключи (length, setItem, getItem и т. д.) } console.log(`${key}: ${localStorage.getItem(key)}`); } // или // Object.keys возвращает ключи, принадлежащие только объекту (без ключей прототипа) for(key of Object.keys(localStorage)){ console.log(`${key}: ${localStorage.getItem(key)}`); } |
Хранилище sessionStorage
Объект sessionStorage используется гораздо реже, чем localStorage по причинам, указанным ниже.
Свойства и методы такие же, как и у localStorage
Основные особенности sessionStorage:
- sessionStorage существует только в рамках текущей вкладки браузера.
- Другая вкладка браузера с той же страницей будет иметь другое хранилище.
- Данные продолжают существовать после перезагрузки страницы, но не после закрытия (открытия) вкладки.
Событие storage
Подробнее https://developer.mozilla.org
С примерами https://itchief.ru/javascript/localstorage#event
Когда обновляются данные в localStorage или sessionStorage, генерируется событие storage со следующими свойствами (только для чтения):
- key – ключ, который обновился (null, если вызван метод clear());
- oldValue – старое значение (null, если ключ добавлен впервые);
- newValue – новое значение (null, если ключ был удалён);
- url – url документа, где произошло обновление key;
- storageArea – объект localStorage или sessionStorage, где произошло обновление key.
Событие storage генерируется на всех вкладках, принадлежащих этому источнику, кроме той, которая вызвала эти изменения в Storage.
Представьте, что у вас есть два окна с одним и тем же сайтом. Хранилище localStorage разделяется между ними. Вы можете открыть эту страницу в двух окнах браузера, чтобы проверить приведённый ниже код.
Теперь, если оба окна слушают window.onstorage, то каждое из них будет реагировать на обновления, произошедшие в другом окне.
1 2 3 4 5 6 7 8 |
// срабатывает при обновлениях, сделанных в том же хранилище из других документов window.onstorage = event => { if (event.key != 'now') return; alert(event.key + ':' + event.newValue + " at " + event.url); }; localStorage.setItem('now', Date.now()); |
Обратите внимание, что событие также содержит: event.url – url-адрес документа, в котором данные обновились.
Также event.storageArea содержит объект хранилища – событие одно и то же для sessionStorage и localStorage, поэтому event.storageArea ссылается на то хранилище, которое было изменено. Мы можем захотеть что-то записать в ответ на изменения.
Это позволяет разным окнам одного источника обмениваться сообщениями.