← Назад к вопросам

В чем разница между localStorage и SessionStorage?

1.0 Junior🔥 111 комментариев
#Другое

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница Между localStorage и sessionStorage

Это хороший вопрос, который показывает понимание браузерного хранилища. Оба это механизмы для хранения данных на клиенте, но они используются в разных сценариях.

Основные Отличия

localStorage

  • Время жизни: Неограниченно (пока пользователь не очистит)
  • Область действия: Один браузер, один домен
  • Размер: ~5-10 MB (зависит от браузера)
  • Синхронизация: Синхронен (блокирует UI)

sessionStorage

  • Время жизни: Только в течение сессии (закрытие вкладки = удаление)
  • Область действия: Одна вкладка, один домен
  • Размер: ~5 MB
  • Синхронизация: Синхронен (блокирует UI)

Таблица Сравнения

┌──────────────────────┬──────────────────────┬────────────────────────┐
│ Параметр             │ localStorage         │ sessionStorage         │
├──────────────────────┼──────────────────────┼────────────────────────┤
│ Время жизни          │ Постоянно            │ Пока открыта вкладка   │
│ Область действия     │ Весь браузер, домен  │ Только эта вкладка     │
│ Синхронизация между  │ Да (storage event)   │ Нет                    │
│ вкладками            │                      │                        │
│ Когда очищается      │ Вручную или в коде   │ При закрытии вкладки   │
│ Использование        │ Долгосрочные данные  │ Временные данные       │
└──────────────────────┴──────────────────────┴────────────────────────┘

localStorage — Долгосрочное Хранилище

Пример: Сохранение Preferences

// Пользователь выбирает тему
function setTheme(theme: 'light' | 'dark') {
  // Сохраняем в localStorage (помещается даже после перезагрузки)
  localStorage.setItem('theme', theme);
  document.body.setAttribute('data-theme', theme);
}

// При загрузке страницы (даже через неделю)
function initializeTheme() {
  const savedTheme = localStorage.getItem('theme');
  if (savedTheme) {
    document.body.setAttribute('data-theme', savedTheme);
  }
}

Типичные использования localStorage:

  • Предпочтения пользователя (тема, язык, размер шрифта)
  • Кеш данных (списки товаров, результаты поиска)
  • Токены доступа (но НЕ рекомендуется!)
  • Аналитика и отслеживание

Проблема с localStorage для токенов:

// ❌ Плохо — хранить JWT в localStorage
localStorage.setItem('authToken', jwtToken);

// Почему плохо:
// 1. XSS атака: вредоносный JavaScript может прочитать
const token = localStorage.getItem('authToken');
console.log(token); // Украдено!

// 2. localStorage доступен любому скрипту на странице
// 3. CSRF атаки могут использовать этот токен

Правильное хранилище для токенов: httpOnly cookies (не доступны из JavaScript).

sessionStorage — Временное Хранилище

Пример: Сохранение State Формы

// Пользователь заполняет сложную форму
function saveFormState(formId: string, formData: any) {
  // Сохраняем в sessionStorage (если перезагрузит страницу — восстановим)
  sessionStorage.setItem(`form_${formId}`, JSON.stringify(formData));
}

function restoreFormState(formId: string) {
  const saved = sessionStorage.getItem(`form_${formId}`);
  if (saved) {
    return JSON.parse(saved);
  }
  return null;
}

// Если пользователь закроет вкладку — данные удалятся
// (что правильно — новая сессия, новые данные)

Типичные использования sessionStorage:

  • Временные данные (страницу назад, поиск текущей сессии)
  • State между страницами в одной сессии
  • Данные, которые НЕ должны хранится после закрытия вкладки
  • Флаги для UI (показывать tutorial или нет)

Практические Примеры

Пример 1: Multi-tab Синхронизация (localStorage)

// Вкладка 1: меняет тему
localStorage.setItem('theme', 'dark');

// Вкладка 2: слушает изменения
window.addEventListener('storage', (event) => {
  if (event.key === 'theme') {
    // event.newValue = 'dark'
    applyTheme(event.newValue);
  }
});

// Благодаря storage event, вкладка 2 узнает об изменении!
// sessionStorage этого НЕ поддерживает

Пример 2: Восстановление После Перезагрузки (localStorage)

// App.tsx
function useAuthToken() {
  const [token, setToken] = useState<string | null>(() => {
    // При загрузке приложения восстанавливаем токен
    return localStorage.getItem('token');
  });

  const saveToken = (newToken: string) => {
    setToken(newToken);
    localStorage.setItem('token', newToken);
  };

  const logout = () => {
    setToken(null);
    localStorage.removeItem('token');
  };

  return { token, saveToken, logout };
}

Пример 3: Сохранение Drafts (sessionStorage)

// Пользователь пишет комментарий
function saveDraft(postId: string, draft: string) {
  sessionStorage.setItem(`draft_${postId}`, draft);
}

function publishComment(postId: string, draft: string) {
  // После публикации удаляем draft
  sessionStorage.removeItem(`draft_${postId}`);
  // Отправляем на сервер
  api.postComment(postId, draft);
}

function discardDraft(postId: string) {
  sessionStorage.removeItem(`draft_${postId}`);
}

// Если пользователь закроет вкладку — draft удалится
// (это безопасно, потому что это временные данные)

Важные Моменты

1. Оба синхронны

// ❌ Плохо — это блокирует UI
for (let i = 0; i < 1000000; i++) {
  localStorage.setItem(`key_${i}`, `value_${i}`);
}

// Браузер "зависнет" на время
// Пользователь не может кликать, скролить и т.д.

Решение: используй IndexedDB для больших объёмов данных.

2. Размер ограничен

// localStorage есть лимит ~5MB
const data = 'x'.repeat(6 * 1024 * 1024); // 6 MB
try {
  localStorage.setItem('bigData', data);
} catch (e) {
  console.log('QuotaExceededError'); // Превышен лимит
}

3. Только строки

// ❌ localStorage хранит только строки
localStorage.setItem('obj', { name: 'John' });
// Результат: '[object Object]'

// ✅ Правильно
localStorage.setItem('obj', JSON.stringify({ name: 'John' }));
const obj = JSON.parse(localStorage.getItem('obj'));

4. sessionStorage НЕ синхронизируется между вкладками

// Вкладка 1
sessionStorage.setItem('data', 'hello');

// Вкладка 2
console.log(sessionStorage.getItem('data')); // null!
// sessionStorage изолирована по вкладкам

// Если нужна синхронизация → используй localStorage + storage event

Когда Использовать Что

Используй localStorage:

  • Предпочтения пользователя (будут при следующем визите)
  • Кеш данных (можешь использовать неделями)
  • Долгосрочные данные (пароли и токены — ТОЛЬКО в httpOnly cookies!)

Используй sessionStorage:

  • Временные данные (пока открыта вкладка)
  • State в multi-step форм (при перезагрузке обновится)
  • Данные, которые НЕ должны быть "липкими" (не должны сохраняться после закрытия вкладки)

Лучшие Практики

// Оберни в try-catch (может быть ошибка квоты)
function safeSetStorage(storage: Storage, key: string, value: string) {
  try {
    storage.setItem(key, value);
  } catch (e) {
    if (e instanceof DOMException && e.code === 22) {
      // QuotaExceededError
      console.log('Storage is full');
      // Очисти старые данные
      cleanupOldData(storage);
    }
  }
}

// Не забывай правила
function getData(key: string) {
  const data = localStorage.getItem(key);
  if (!data) return null;
  try {
    return JSON.parse(data);
  } catch (e) {
    console.error('Failed to parse stored data');
    return null;
  }
}

Альтернативы

IndexedDB — для больших объёмов данных

// асинхронно, поддерживает индексы, транзакции
const db = new IndexedDB('myApp');
await db.store('users').add({ id: 1, name: 'John' });

Service Worker Cache — для кеша сетевых запросов

// Кеш HTTP ответов
await caches.open('my-cache').then(cache => {
  cache.add('/api/users');
});

Заключение

localStorage: для долгосрочных данных (дни, недели, месяцы) sessionStorage: для временных данных (текущая сессия)

Оба синхронны и имеют ограничения, поэтому для больших данных используй IndexedDB.

И помни: НИКОГДА не храни чувствительные данные (JWT, пароли) в localStorage. Используй httpOnly cookies.