Урок по треку Браузер и DOM 6 мин

Хранилища браузера за 6 минут

Cookie, localStorage, sessionStorage, IndexedDB и Cache API: объём, срок жизни и доступ.

У браузера несколько мест, где сайт может хранить данные. Они отличаются объёмом, сроком жизни, тем, кто их видит, и тем, уходят ли они на сервер.

Cookie

Маленькие пары «имя=значение» (около 4 КБ на одну куку), которые браузер автоматически отправляет на сервер в заголовке Cookie с каждым подходящим запросом. Сервер ставит их заголовком Set-Cookie.

Set-Cookie: session=abc123; Path=/; Max-Age=86400; Secure; HttpOnly; SameSite=Lax

Атрибуты:

  • Expires / Max-Age - срок жизни. Без них кука сессионная и умрёт с закрытием браузера.
  • Domain, Path - для каких адресов отправлять.
  • Secure - только по HTTPS.
  • HttpOnly - недоступна из JS (document.cookie её не покажет). Защищает сессию от кражи через XSS.
  • SameSite - отправлять ли куку при запросах с других сайтов: Strict, Lax, None (с None обязателен Secure). Подробно в модуле про безопасность.

Из JS: document.cookie читает строку всех доступных кук, а присваивание document.cookie = 'theme=dark; max-age=3600' добавляет или меняет одну куку, остальные не трогает.

localStorage и sessionStorage

Web Storage: синхронный API «ключ-строка», порядка 5 МБ на origin.

localStorage.setItem('theme', 'dark');
localStorage.getItem('theme'); // 'dark'
localStorage.setItem('user', JSON.stringify({ id: 1 })); // объекты только через JSON
  • localStorage живёт, пока его не очистят: переживает перезапуск браузера. Общий для всех вкладок одного origin.
  • sessionStorage живёт, пока открыта вкладка, и у каждой вкладки свой. Переживает перезагрузку страницы. При дублировании вкладки копируется.

Оба привязаны к origin: протокол + домен + порт. http://site.ru и https://site.ru видят разные хранилища.

Событие storage приходит в другие вкладки того же origin, когда меняется localStorage. В вкладке, которая сделала запись, оно не срабатывает. Так синхронизируют, например, выход из аккаунта во всех вкладках.

Минусы: API синхронный и блокирует главный поток, хранит только строки, недоступен в воркерах, доступен любому скрипту на странице. Токены и секреты там держать опасно: при XSS их сразу украдут.

IndexedDB

Полноценная асинхронная база в браузере: хранилища объектов, индексы, транзакции. Хранит почти любые данные через structured clone: объекты, Date, Blob, ArrayBuffer. Объём намного больше, чем у Web Storage: это часть общей квоты, которая зависит от свободного места на диске. Доступна в воркерах.

API на событиях неудобен, поэтому обычно берут обёртку (например, idb или Dexie).

Cache API

caches хранит пары «запрос → ответ». Главный пользователь это Service Worker: он кладёт туда статику и отдаёт её офлайн. Доступен и из обычной страницы. Это не HTTP-кеш браузера: управляет им только ваш код.

Квоты и очистка

Браузер может удалить данные сайта при нехватке места. navigator.storage.estimate() показывает занято и доступно, navigator.storage.persist() просит не удалять данные автоматически. Safari может стереть хранилища, созданные скриптом, если пользователь не взаимодействовал с сайтом 7 дней.

Сводка

ОбъёмСрокНа серверИз JS
Cookie~4 КБпо Max-Age или сессияда, самесли нет HttpOnly
localStorage~5 МБбессрочнонетда, синхронно
sessionStorage~5 МБвкладканетда, синхронно
IndexedDBбольшойбессрочнонетда, асинхронно
Cache APIбольшойбессрочнонетда, асинхронно

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

  • Хранить JWT в localStorage и считать это безопасным.
  • Класть объект в setItem без JSON.stringify и получать "[object Object]".
  • Ждать событие storage в той же вкладке.
  • Думать, что sessionStorage общий для вкладок.

Что спросят на собесе

  • Разница между cookie, localStorage и sessionStorage.
  • Где хранить токен авторизации и почему.
  • Что делают HttpOnly, Secure, SameSite.
  • Когда нужен IndexedDB.
  • Как синхронизировать состояние между вкладками.

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.