Серверные фреймворки, такие как Django или Spring, в основном используют управление сессиями (Session) на сервере и идентификацию клиента через куки (Cookie). Это удобно, так как сервер управляет состоянием.

Однако в среде SPA (Single Page Application), как React, Vue, Angular, клиент (браузер) выполняет множество задач. Основная связь с сервером осуществляется через API, а такие вещи, как состояние пользователя или настройки пользовательского интерфейса, часто управляются непосредственно на стороне клиента.

В такой ситуации необходимо решить, "где" сохранять данные, и браузер предлагает несколько типов хранилищ для этого. Четкое понимание характеристик и назначения каждого хранилища является ключевым для эффективной разработки SPA.

Сегодня мы рассмотрим основные хранилища браузера: куки (Cookie), локальное хранилище (Local Storage), сессионное хранилище (Session Storage) и IndexedDB.




Куки являются основным типом браузерного хранилища. Они изначально были разработаны для поддержания состояния (Stateful) между сервером и клиентом.

  • Характеристики:

    • Малый объем: ограничение объема примерно 4KB.

    • Передача на сервер: самое важное свойство. Куки автоматически отправляются на сервер со всеми HTTP-запросами. Это полезно, когда сервер должен знать состояние клиента, но может снизить производительность из-за ненужной передачи данных.

    • Срок действия: дату и время истечения можно установить с помощью свойств Expires или Max-Age. Если не установить, работает как сессионное куки (удаляется при закрытии браузера).

    • Опции безопасности: Настройки безопасности, такие как HttpOnly (защита от доступа JavaScript), Secure (отправка только по HTTPS).

  • Основные применения:

    • Аутентификация (Authentication): хранение токенов аутентификации (JWT и др.), чтобы сервер мог идентифицировать пользователя при переходе между страницами. (особенно используется с опцией HttpOnly)

    • Отслеживание пользователей и реклама: используется для отслеживания истории посещений или поведения пользователей. (например, Google Analytics)

    • Всплывающее окно 'Не показывать сегодня'


2. Локальное хранилище (Local Storage)

Часть API веб-хранилища (Web Storage), введенного в HTML5. Появилось для устранения недостатков куки (малый объем, автоматическая передача на сервер).

  • Характеристики:

    • Большой объем: хотя он отличается в разных браузерах, в большинстве случаев объем составляет 5MB ~ 10MB.

    • Без отправки на сервер: локальное хранилище хранит данные только на клиенте и не отправляет их на сервер автоматически. Это хорошо для хранения данных, которые не нужны серверу.

    • Постоянство: данные сохраняются навсегда. Данные не исчезнут, пока пользователь не очистит кэш браузера или не выполнит вызов localStorage.removeItem() через JavaScript.

    • Удобный API: предоставляет простой в использовании API, такой как localStorage.setItem('key', 'value'), localStorage.getItem('key'). (можно хранить только строки)

  • Основные применения:

    • Сохранение пользовательских настроек: используется для хранения UI-настроек, выбраных пользователем, таких как темы темного/светлого режима и определения языка.

    • Хранение не конфиденциальных данных: такие как список последнего просмотренного контента, функция автосохранения и т.д.

    • Кэширование данных: кэширование данных, которые не часто изменяются, среди ответов API, чтобы уменьшить ненужные запросы.


3. Сессионное хранилище (Session Storage)



Практически все характеристики локального хранилища сопоставимы, но есть серьезные отличия в жизненном цикле данных (Life Cycle).

  • Характеристики:

    • Большой объем: также предлагает объем примерно 5MB.

    • Без отправки на сервер: данные хранятся только на клиенте.

    • Сессионный жизненный цикл: данные ограничены текущей вкладкой (или окном) браузера. При закрытии вкладки все данные в сессионном хранилище удаляются немедленно.

    • Изоляция данных: даже в рамках одного домена данные не разделяются между различными вкладками.

  • Основные применения:

    • Хранение одноразовых данных: используется для хранения информации, которая должна быть доступна только в текущей вкладке.

    • Временные данные формы: используется для временного хранения вводимых данных до закрытия вкладки в многоступенчатых формах, таких как регистрация или опросы.

    • Сохранение данных при обновлении: данные должны сохраняться при обновлении страницы, но исчезать при закрытии вкладки.


4. IndexedDB

Если локальное и сессионное хранилище представляют собой простые хранилища типа Key-Value, то IndexedDB является системой управления транзакционными базами данных, встроенной в браузер.

  • Характеристики:

    • Большое хранилище: может хранить от сотен мегабайт до нескольких гигабайт в зависимости от доступного дискового пространства пользователя (что может различаться по политике браузера).

    • Разнообразные типы данных: можно хранить не только строки, но и объекты JavaScript, файлы (Blob), массивы и т.д.

    • Поддержка транзакций: обеспечивает целостность и согласованность данных. Несколько операций могут быть объединены в одну транзакцию.

    • Асинхронный API: все операции IndexedDB обрабатываются асинхронно. Это помогает поддерживать отзывчивость приложения во время чтения и записи больших объемов данных, не блокируя основной UI поток.

    • Поддержка индексов: индексы могут быть созданы для очень быстрого поиска данных по определенным полям.

  • Недостатки:

    • Сложный API: API значительно более сложный и трудный в использовании по сравнению с localStorage. (по этой причине часто используются обертки, такие как Dexie.js, idb).
  • Основные применения:

    • Оффлайн веб-приложения (PWA): используются для хранения основных данных в приложениях, которые должны работать без сетевого подключения (например, оффлайн-редакторы документов).

    • Кэширование состояния больших приложений: используется для сохранения истории предыдущих разговоров браузера в таких приложениях, как Gemini или ChatGPT, или для управления сложными пользовательскими данными.

    • Временное хранение пользовательского контента: служит безопасным местом для хранения длинных текстов или данных редактирования изображений, которые пользователь создает до их загрузки на сервер.


5. Сравнение на одном экране

A conceptual diagram illustrating different types of web browser storage: Cookie, Local Storage, Session Storage, and IndexedDB, each with symbolic icons representing their characteristics within a stylized browser window.

Характеристики четырех хранилищ можно кратко изложить в таблице ниже.

Критерий Куки (Cookie) Локальное хранилище Сессионное хранилище IndexedDB
Объем ~ 4KB ~ 5-10MB ~ 5MB ~ GB+ (большой объем)
Срок действия Настройка вручную Постоянный При закрытии вкладки Постоянный
Передача на сервер Да (автовыдача) Нет (только клиентское) Нет (только клиентское) Нет (только клиентское)
Область доступа Тот же домен Тот же источник Текущая вкладка Тот же источник
Тип данных Строка Строка Строка Объект, файл, Blob и т.д.
API Синхронный (сложный) Синхронный (удобный) Синхронный (удобный) Асинхронный (сложный)
Функция поиска Нет Нет Нет Да (с использованием индекса)

6. Вывод: что и когда использовать?

При разработке SPA, такой как React, полезно четко различать назначения этих четырех хранилищ.

  • Куки (Cookie):

    • Используйте для данных, которые сервер должен знать. (например, токены аутентификации с высоким уровнем безопасности)

    • Рекомендуется использовать опцию HttpOnly для защиты токенов от XSS-атак.

  • Локальное хранилище (Local Storage):

    • Используйте для простых данных, которые должны сохраняться даже при выключении браузера.

    • (например, настройки пользовательского интерфейса, выбор языка)

  • Сессионное хранилище (Session Storage):

    • Используйте для временных данных, необходимых только во время текущей работы (вкладки).

    • (например, временное хранение данных во многоступенчатых формах)

  • IndexedDB:

    • Используйте для структурированных больших объемов данных или когда требуется поддержка оффлайна.

    • (например, кэширование сложных состояний приложения, запись истории разговоров, оффлайн-данные документов)

Важная примечание по безопасности: локальное хранилище, сессионное хранилище и IndexedDB легко доступны через JavaScript. Это делает их уязвимыми для атак XSS (Cross-Site Scripting). Пароли, личная идентификационная информация, чувствительные токены аутентификации никогда не следует сохранять здесь. (Наиболее безопасным способом является использование HttpOnly куки для токенов аутентификации.)