localStorage: читаем настройки как недоверенные данные

3 мин чтения

Как безопасно прочитать настройки из localStorage и сохранить работоспособность страницы при ошибке хранения.

Настройки из браузера нужно проверить
  1. ЧтениеПерехватываем ошибки доступа и разбора JSON
  2. ВалидацияПроверяем версию формата и значения
  3. ПрименениеИспользуем допустимые настройки или значения по умолчанию

В localStorage осталась тема интерфейса от старой версии сайта. Новый код ждёт объект, а находит строку другого формата — и страница ломается при открытии. Чтобы пользователь не терял доступ из-за одной настройки, сохранённые данные нужно разобрать и проверить. А если хранилище недоступно, взять значения по умолчанию.

Чтение и проверка настроек

function readPreferences() {
  const fallback = { version: 1, theme: 'light', pageSize: 20 };
  try {
    const raw = localStorage.getItem('reader-preferences');
    if (raw === null) return fallback;
    const value = JSON.parse(raw);
    if (value === null || typeof value !== 'object' || Array.isArray(value)
        || value.version !== 1
        || !['light', 'dark'].includes(value.theme)
        || ![10, 20, 50].includes(value.pageSize)) return fallback;
    return { version: 1, theme: value.theme, pageSize: value.pageSize };
  } catch (error) {
    return fallback;
  }
}
function savePreferences(value) {
  try {
    localStorage.setItem('reader-preferences', JSON.stringify(value));
    return true;
  } catch (error) {
    return false;
  }
}

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

Хранилище может отказать

Доступ к localStorage и запись могут завершиться исключением из-за ограничений происхождения, настроек клиента или доступного объёма. Обёртка должна охватывать сам доступ, а не только JSON.parse. Возвращаемый savePreferences признак сообщает, удалось ли запомнить настройки; интерфейс может продолжать работать с выбранным значением в памяти. Не обещайте пользователю сохранение между посещениями, если запись фактически не состоялась.

Хранилище относится к origin и доступно сценариям этого происхождения. Оно не подходит для паролей и не служит доверенным источником прав доступа. Операции синхронные, поэтому большой документ или частые записи на каждое движение указателя могут мешать интерфейсу. Проверяйте страницу через HTTP или HTTPS: при открытии локального файла поведение хранилища может отличаться. Если важна синхронизация вкладок, отдельно обработайте событие storage с повторной валидацией новых данных.

Что передать для проверки

Проверьте ключ, которого нет, повреждённый JSON, null, массив, незнакомую версию и правильный объект. При запрете хранения страница должна открыться со стандартными настройками. После успешного сохранения перезагрузите её и проверьте восстановление. Локальные настройки при этом всё равно остаются данными браузера, которым нельзя доверять права доступа.

Источники и дальнейшее чтение