W3docs

JavaScript LocalStorage, SessionStorage

Узнайте, как использовать localStorage и sessionStorage в JavaScript: хранение данных, JSON, событие storage и обработка ошибок.

localStorage и sessionStorage — это два объекта, составляющих Web Storage API — простейший способ хранить данные в браузере между перезагрузками страницы. Оба хранят информацию в виде строковых пар ключ/значение, привязанных к origin страницы (протокол + хост + порт), и оба предоставляют одинаковый набор методов. Единственное различие — время жизни данных: localStorage хранит их бессрочно, тогда как sessionStorage удаляет при закрытии вкладки.

На этой странице рассматривается полный API, безопасное хранение объектов с помощью JSON, реагирование на изменения в других вкладках через событие storage, обработка ошибок, которые могут возникать при работе с этими API, и ситуации, когда лучше использовать более мощное хранилище.

Внимание

Никогда не храните конфиденциальную информацию (пароли, токены, персональные данные) в localStorage или sessionStorage. Любой JavaScript, выполняющийся на странице, — включая сторонние скрипты, — может её прочитать, и она полностью уязвима для атак межсайтового скриптинга (XSS).

Понимание LocalStorage в JavaScript

localStorage хранит данные в браузере пользователя постоянно, без срока действия. Данные сохраняются при закрытии вкладки, закрытии браузера и даже перезагрузке компьютера — они остаются до тех пор, пока их не очистит ваш код или пользователь. Данные привязаны к origin, поэтому https://example.com не может прочитать то, что сохранил https://other.com.

Как использовать LocalStorage

API небольшой. Вы записываете пару с помощью setItem(key, value), читаете её с помощью getItem(key) и удаляете с помощью removeItem(key). Чтение несуществующего ключа возвращает null (а не undefined). API также предоставляет:

  • clear() — удалить все элементы для данного origin.
  • key(index) — получить имя ключа по заданному индексу.
  • length — количество сохранённых элементов.
  • событие storage, которое можно слушать для обнаружения изменений в других вкладках.
javascript— editable
Примечание

Операции с хранилищем являются синхронными и выполняются в основном потоке, поэтому чтение или запись больших объёмов данных может блокировать отрисовку интерфейса. Для больших или структурированных данных предпочтительнее использовать IndexedDB.

Хранение объектов и массивов с помощью JSON

Самая распространённая ошибка при работе с Web Storage — забыть, что всё хранится как string. Если передать object в setItem, он будет молча преобразован через toString(), и вы получите бесполезное значение "[object Object]". Решение — сериализовать с помощью JSON.stringify при записи и JSON.parse при чтении.

javascript— editable

Подробнее о преобразовании значений в строки и обратно читайте в разделе Работа с JSON.

Перебор сохранённых элементов

Используйте length вместе с key(index) для перебора всего содержимого хранилища или читайте ключи через Object.keys:

javascript— editable

Практическое применение: создание переключателя тем с помощью LocalStorage

Рассмотрим сценарий, в котором нужно сохранить предпочтительную тему пользователя (светлую или тёмную), чтобы она сохранялась между сессиями. В следующем примере HTML, CSS и JavaScript объединены в один блок для простоты.

<style>
    :root {
        --bg-color: #ffffff;
        --text-color: #000000;
    }
    .dark {
        --bg-color: #333333;
        --text-color: #ffffff;
    }
    body {
        background-color: var(--bg-color);
        color: var(--text-color);
        transition: background-color 0.5s, color 0.5s;
    }
    button {
        padding: 10px 20px;
        font-size: 16px;
        cursor: pointer;
    }
</style>
<body>
<button onclick="toggleTheme()">Toggle Theme</button>
<script>
    function setTheme(themeName) {
        localStorage.setItem('theme', themeName);
        document.documentElement.className = themeName;
    }

    function toggleTheme() {
        var currentTheme = localStorage.getItem('theme') === 'dark' ? 'dark' : 'light';
        if (currentTheme === 'light') {
            setTheme('dark');
        } else {
            setTheme('light');
        }
    }

    function loadTheme() {
        var theme = localStorage.getItem('theme') || 'light';
        setTheme(theme);
    }

    // Initial theme load
    loadTheme();
</script>
</body>

Этот скрипт проверяет сохранённую тему в LocalStorage или использует по умолчанию 'light'. Затем применяет тему, устанавливая имя класса корневого HTML-элемента, что позволяет CSS соответствующим образом настраивать стили.

SessionStorage: временное хранение данных в JavaScript

В то время как LocalStorage предназначен для хранения данных без срока действия, SessionStorage предоставляет способ хранить данные в течение текущей сессии страницы. Данные, сохранённые в SessionStorage, очищаются по окончании сессии страницы — то есть при закрытии вкладки или окна.

Как использовать SessionStorage

Ниже приведён базовый пример использования SessionStorage. Методы и синтаксис идентичны localStorage — отличается только время жизни. Значение sessionStorage также привязано к вкладке: открытие того же сайта в новой вкладке начинается с пустым sessionStorage, тогда как новая вкладка использует тот же localStorage.

javascript— editable

Пример: использование SessionStorage для автосохранения данных формы

Представьте, что у вас есть форма, которую пользователь может заполнять, но есть риск, что он случайно закроет браузер. Вы можете использовать SessionStorage для временного сохранения данных формы.


<body>
    <div>Start writing an email address in the following input. Refresh the page in the middle of your typing, and you'll see that the page remembers what you entered before.</div>
    <br />
    <input type="email" id="email"/>
</body>
<script>
window.onload = function() {
    const email = sessionStorage.getItem('email');
  
    if (email) {
        alert('email found from session storage: ' + email);
        document.getElementById('email').value = email;
    }

    document.getElementById('email').oninput = function() {
        sessionStorage.setItem('email', this.value);
    };
};
</script>

Этот код автоматически загружает сохранённый адрес электронной почты при загрузке страницы и обновляет элемент SessionStorage при каждом изменении поля email. Чтобы проверить, нажмите кнопку «попробуйте сами», введите что-нибудь в поле и обновите страницу. Значение сохранится после обновления.

Информация

Всегда учитывайте ограничения по размеру перед сохранением данных (обычно около 5 МБ как для LocalStorage, так и для SessionStorage).

LocalStorage vs. SessionStorage

Оба объекта используют одинаковый API, одинаковую область видимости по origin и одинаковую модель хранения только строк. Практические различия сводятся к времени жизни и видимости:

ХарактеристикаlocalStoragesessionStorage
Время жизниДо явной очисткиДо закрытия вкладки
Сохраняется при перезапуске вкладки/браузераДаНет
Общий доступ между вкладками одного originДаНет (каждая вкладка изолирована)
Ёмкость~5 МБ~5 МБ
Вызывает событие storage в других вкладкахДаНет

Используйте sessionStorage, когда данные имеют смысл только в течение текущего посещения — многошаговый мастер, незавершённая форма, позиция прокрутки. Используйте localStorage для настроек и других данных, которые должны сохраняться между посещениями.

Реагирование на изменения с помощью события storage

Когда localStorage изменяется в одной вкладке, браузер генерирует событие storage во всех остальных вкладках того же origin (но не в той вкладке, которая внесла изменения). Это стандартный способ синхронизировать несколько вкладок — например, разлогинивать пользователя везде, когда он выходит из системы в одной вкладке.

window.addEventListener('storage', (event) => {
  console.log('Key changed:', event.key);
  console.log('Old value:', event.oldValue);
  console.log('New value:', event.newValue);
  console.log('URL of the page that made the change:', event.url);
});

// In another tab, this would trigger the handler above:
// localStorage.setItem('theme', 'dark');

Свойства key, oldValue и newValue объекта события точно сообщают, что изменилось. Обратите внимание, что sessionStorage не вызывает это событие в других вкладках, поскольку его данные никогда не являются общими.

Обработка ошибок и граничных случаев

Вызовы методов хранилища могут выбрасывать исключения, поэтому продакшн-код не должен предполагать их всегда успешное выполнение:

  • Превышение квоты. Запись данных сверх лимита ~5 МБ выбрасывает QuotaExceededError. Оборачивайте запись в try...catch, если значение может быть большим.
  • Отключено или режим приватности. В некоторых браузерах (или при строгих настройках приватности) хранилище может быть недоступно, и даже обращение к localStorage может выбросить SecurityError. Перед использованием выполняйте проверку доступности.
javascript— editable

Для больших наборов данных, сложных запросов или хранения бинарных данных лучше подойдёт более мощная клиентская база данных, например IndexedDB. Если данные нужно автоматически передавать с каждым запросом на сервер, используйте cookies. Также можно проверить оставшуюся ёмкость и запросить постоянство хранилища с помощью Storage API.

Заключение

LocalStorage и SessionStorage предоставляют мощные возможности для улучшения пользовательского опыта за счёт эффективного управления данными в веб-приложениях. Понимая их возможности и ограничения, разработчики могут принимать обоснованные решения о наилучшем использовании этих инструментов в своих проектах.

Практика

Практика
Какие из следующих утверждений верны относительно localStorage и sessionStorage в JavaScript?
Какие из следующих утверждений верны относительно localStorage и sessionStorage в JavaScript?
Was this page helpful?