Web Storage: localStorage и sessionStorage

localStorage и sessionStorage — браузерные хранилища ключ-значение, позволяющие сохранять строковые данные на стороне клиента без участия сервера.

Зачем нужно

Web Storage решает задачу постоянного или временного хранения данных прямо в браузере. В отличие от cookies, эти хранилища не передаются на сервер с каждым запросом и имеют значительно больший объём (обычно 5–10 МБ). Это делает их удобными для кеширования настроек, черновиков, состояния UI.

Где используется

  • Сохранение пользовательских настроек (тема, язык, размер шрифта)
  • Кеширование данных форм / черновиков
  • Хранение JWT-токенов (с осторожностью из-за XSS)
  • Запоминание последнего состояния приложения между сессиями

Различия localStorage и sessionStorage

Свойство localStorage sessionStorage
Время жизни До явного удаления До закрытия вкладки
Область видимости Все вкладки одного origin Только текущая вкладка
Объём ~5–10 МБ ~5 МБ

API: основные методы

// Запись
localStorage.setItem('key', 'value');
localStorage.setItem('user', JSON.stringify({ name: 'Иван', age: 30 }));

// Чтение
const val = localStorage.getItem('key');          // 'value' или null
const user = JSON.parse(localStorage.getItem('user'));

// Удаление
localStorage.removeItem('key');
localStorage.clear(); // удалить всё

// Количество ключей
console.log(localStorage.length);

// Перебор
for (let i = 0; i < localStorage.length; i++) {
  const key = localStorage.key(i);
  console.log(key, localStorage.getItem(key));
}

Практический пример: сохранение настроек темы

function saveTheme(theme) {
  localStorage.setItem('theme', theme);
  document.documentElement.dataset.theme = theme;
}

function loadTheme() {
  const saved = localStorage.getItem('theme') || 'light';
  document.documentElement.dataset.theme = saved;
  return saved;
}

// При загрузке страницы
loadTheme;

// При смене темы
document.getElementById('toggle').addEventListener('click', () => {
  const current = localStorage.getItem('theme') || 'light';
  saveTheme(current === 'light' ? 'dark' : 'light');
});

Пример: sessionStorage для черновика формы

const textarea = document.getElementById('draft');

// Восстановить черновик при загрузке
textarea.value = sessionStorage.getItem('draft') || '';

// Сохранять при вводе
textarea.addEventListener('input', () => {
  sessionStorage.setItem('draft', textarea.value);
});

// Очистить при отправке
document.getElementById('form').addEventListener('submit', () => {
  sessionStorage.removeItem('draft');
});

Событие storage

// Срабатывает в других вкладках того же origin при изменении localStorage
window.addEventListener('storage', (event) => {
  console.log('Ключ:', event.key);
  console.log('Старое значение:', event.oldValue);
  console.log('Новое значение:', event.newValue);
  console.log('URL изменившей вкладки:', event.url);
});

Частые ошибки

  • Хранение объектов без JSON.stringifysetItem принимает только строки; объект превратится в "[object Object]".
  • Доверие хранилищу в безопасных сценарияхlocalStorage доступен через XSS, не стоит хранить там чувствительные данные без необходимости.
  • Превышение квоты — запись может бросить QuotaExceededError; всегда оборачивайте в try/catch.
  • Синхронность — все операции синхронны и блокируют поток; для больших данных лучше IndexedDB.

Связанные темы

Ресурсы