Решение ошибки QUOTA_EXCEEDED_ERR в Safari: localStorage
Быстрый ответ
Ошибку QUOTA_EXCEEDED_ERR
в localStorage
браузера Safari, как правило, вызывает режим приватного просмотра (инкогнито), где допустимый объем данных существенно ограничен. Чтобы избежать этой проблемы, попробуйте добавить объект и обработать исключение следующим образом:
try {
// Производим тестовое действие
localStorage.setItem('test', 'data');
} catch (e) {
if (e.code === 22) {
// Ограничение хранилища или активирован приватный режим
alert('Не удалось сохранить данные: превышен лимит хранилища или активирован режим приватного просмотра.');
}
}
Формируйте сообщения о возникновении проблем и ведите защиту операций с хранилищем тактично и грамотно!
Разбираемся с особенностями localStorage
Отличия в браузерах
Несмотря на то, что localStorage универсален, его работа в разных браузерах имеет свои особенности. Например, в Safari при включении приватного режима устанавливаются настолько строгие квоты, что даже попытка сохранить небольшой объект может вызвать ошибку QUOTA_EXCEEDED_ERR
.
Определение приватного режима
Приватный режим может быть не всегда очевиден. Однако, его наличие может проявиться при попытке добавить данные в localStorage. Для безопасности оберните эту проверку в функцию:
function isLocalStorageSupported() {
var testKey = 'test', storage = window.localStorage;
try {
// Проводим проверку
storage.setItem(testKey, '1');
// Теперь этот ключ можно удалить
storage.removeItem(testKey);
return true;
} catch (error) {
// Произошла ошибка
return false;
}
}
Если функция вернёт false
, использовать localStorage для сохранения данных не рекомендуется.
Альтернативное хранилище данных
Если localStorage не доступен, например, в режиме приватного просмотра, можно использовать sessionStorage
. Интерфейс последнего аналогичен localStorage, но не сталкивается с ограничениями по объему данных в приватном режиме.
Расширенные приемы работы с исключениями
Создание универсального обработчика хранилища
Для более универсальной работы с хранилищем вы можете создать собственный класс с использованием подхода feature detection (по аналогии с Modernizr). Такой класс позволит выбирать между localStorage, sessionStorage или другими методами, например, cookies:
class StorageHandler {
constructor() {
// Выбираем оптимальный метод хранения данных
this.storage = this.selectStorage();
}
selectStorage() {
if (isLocalStorageSupported()) {
return localStorage;
} else if (window.sessionStorage) {
return sessionStorage;
} else {
// Определяем альтернативный метод.
}
}
setItem(key, data) {
try {
// Пытаемся сохранить данные
this.storage.setItem(key, data);
} catch (e) {
// В случае ошибки...
}
}
// Не забывайте реализовать методы getItem и removeItem.
}
Отслеживание изменений в браузере Safari
Изменения в различных версиях Safari могут значительно влиять на поведение хранилища, поскольку Apple время от времени меняет свою политику относительно работы с данными. Следите за релизами и обновлениями браузера, а также изучайте изменения в коде, например, r215315, с последующим внесением корректировок в свой код.
Глобальный перехват исключений
Если вы не хотите создавать собственные классы, можно использовать глобальную «заглушку», которая игнорирует исключения, вызываемые localStorage во время использования приватного режима:
(function() {
// Заменяем реализацию localStorage.setItem для приватного режима в Safari
var originalSetItem = Storage.prototype.setItem;
Storage.prototype.setItem = function(key, value) {
try {
// Пытаемся сохранить данные
originalSetItem.call(this, key, value);
} catch (e) {
if (e.code === 22) {
// Либо игнорируем ошибку, либо обрабатываем
}
}
};
})();
Визуализация
Представьте себе путешествие (💼):
💼 Разрешенный вес: 10 кг | Текущий вес: 9,5 кг | Предмет для добавления: 2 кг 🏋️♂️
Ошибка LocalStorage напоминает:
👨💻 Добавляем новый предмет:
🏋️♂️ "Слишком тяжёл!"
💼💥 "QUOTA_EXCEEDED_ERR: DOM Exception 22"
Если вы привыкли брать много вещей с собой, вы, наверняка, знакомы со следующим правилом: необходимо избавиться от ненужного:
До: 💼🧳⚖️[👕👖📚🎧🍫(9,5 кг)]
После: 💼🧳⚖️[👕👖📚(7,5 кг)] + 🏋️♂️(2 кг) = ✅
Работайте с вашим хранилищем, как с багажом: находите баланс для удобной работы! 🌐✈️
Углубленное изучение проблем и их решение
Проверка лимитов хранилища
Будьте профессионалами, навыки которых всегда держат наготове. Регулярно проводите проверки текущего и предполагаемого использования вашего хранилища.
Использование «заглушек» и «полифиллов»
Используйте «заглушки» и «полифиллы», чтобы обеспечить согласованность в различных браузерах. Они помогают компенсировать расхождения в поведении браузеров и обеспечивают совместимость функций.
Мониторинг изменений поведения браузера
Разные версии Safari могут вести себя по-разному. После релиза обновления для iOS или Safari выполните экспресс-тест и, при необходимости, внесите корректировки в обработку данных хранилища.
Полезные материалы
- Web Storage API – Веб API | MDN — Обстоятельная документация по Web Storage API.
- javascript – ошибки localStorage в Safari: "QUOTA_EXCEEDED_ERR: DOM Exception 22:..." — дискуссия на Stack Overflow, посвященная проблеме localStorage в Safari.
- Storing Data the Simple HTML5 Way (and a few tricks you might not have known) — Практический обзор функций хранения данных в HTML5, включая localStorage.
- Safari – Apple Developer — Официальные материалы Apple для разработчиков по работе с Safari.
- Can I use... Support tables for HTML5, CSS3, etc — Информационная ссылка, показывающая характеристики и совместимости браузеров с Web Storage, помогающие разработчикам понять специфику работы браузеров.
- Storage for the web | Articles | web.dev — Материал, рассказывающий, как справляться с лимитами хранения данных в веб-приложениях.