QuotaExceededError: исключение Dom 22: была сделана попытка добавить что-то в хранилище, превышающее квоту



использование LocalStorage на iPhone с iOS 7 выдает эту ошибку. Я искал резольвент, но, учитывая, что я даже не просматриваю в частном порядке, ничего не имеет значения.



Я не понимаю, почему localStorage будет отключен по умолчанию в iOS 7, но, похоже, это так? Я проверил на других сайтах, но не повезло. Я даже попробовал протестировать его с помощью этого сайта:http://arty.name/localstorage.html, но не похоже, что это спасает что-нибудь на все по какой-то странной причине.



у кого-нибудь была такая же проблема, только им повезло ее исправить? Должен ли я переключить свой метод хранения?



Я старался изо всех сил отлаживать его, сохраняя только несколько строк информации, но безрезультатно. Я использовал стандарт сохранить.

601   9  

9 ответов:

Это может произойти, когда Safari находится в частном режиме просмотра. В то время как в частном просмотре, локальное хранилище не доступно вообще.

одно из решений состоит в том, чтобы предупредить пользователя о том, что приложение должно работать в непубличном режиме.

обновление: это было исправлено в Safari 11, так что поведение теперь выровнено с другими браузерами.

как уже упоминалось в других ответах, вы всегда будете получать QuotaExceededError в режиме частного браузера Safari как на iOS, так и на OS X, когда localStorage.setItem (или sessionStorage.setItem) называется.

одним из решений является сделать попробовать/поймать или Modernizr проверки в каждом случае использования setItem.

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

https://gist.github.com/philfreo/68ea3cd980d72383c951

// Safari, in Private Browsing Mode, looks like it supports localStorage but all calls to setItem
// throw QuotaExceededError. We're going to detect this and just silently drop any calls to setItem
// to avoid the entire page breaking, without having to do a check at each usage of Storage.
if (typeof localStorage === 'object') {
    try {
        localStorage.setItem('localStorage', 1);
        localStorage.removeItem('localStorage');
    } catch (e) {
        Storage.prototype._setItem = Storage.prototype.setItem;
        Storage.prototype.setItem = function() {};
        alert('Your web browser does not support storing settings locally. In Safari, the most common cause of this is using "Private Browsing Mode". Some settings may not save or some features may not work properly for you.');
    }
}

я использую эту простую функцию, которая возвращает true или false, чтобы проверить доступность localStorage:

isLocalStorageNameSupported = function() {
    var testKey = 'test', storage = window.sessionStorage;
    try {
        storage.setItem(testKey, '1');
        storage.removeItem(testKey);
        return true;
    } catch (error) {
        return false;
    }
}

теперь вы можете проверить localStorage.setItem() доступность перед его использованием. Пример:

if ( isLocalStorageNameSupported() ) {
    // can use localStorage.setItem('item','value')
} else {
    // can't use localStorage.setItem('item','value')
}

мне довелось работать с той же проблемой в iOS 7 (С некоторыми устройствами нет тренажеров).

похоже, что Safari в iOS 7 имеет более низкую квоту хранения, которая, по-видимому, достигается за счет длительного журнала истории.

Я думаю, что лучшей практикой будет поймать исключение.

проект Modernizr имеет простой патч, вы должны попробовать что-то подобное: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js

вот расширенное решение, основанное на ответе DrewT выше, которое использует куки, если localStorage недоступен. Он использует Mozilla библиотека docCookies:

function localStorageGet( pKey ) {
    if( localStorageSupported() ) {
        return localStorage[pKey];
    } else {
        return docCookies.getItem( 'localstorage.'+pKey );
    }
}

function localStorageSet( pKey, pValue ) {
    if( localStorageSupported() ) {
        localStorage[pKey] = pValue;
    } else {
        docCookies.setItem( 'localstorage.'+pKey, pValue );
    }
}

// global to cache value
var gStorageSupported = undefined;
function localStorageSupported() {
    var testKey = 'test', storage = window.sessionStorage;
    if( gStorageSupported === undefined ) {
        try {
            storage.setItem(testKey, '1');
            storage.removeItem(testKey);
            gStorageSupported = true;
        } catch (error) {
            gStorageSupported = false;
        }
    }
    return gStorageSupported;
}

в вашем источнике, просто используйте:

localStorageSet( 'foobar', 'yes' );
...
var foo = localStorageGet( 'foobar' );
...

Как уже было сказано в других ответах, когда в режиме приватного просмотра сафари всегда бросить это исключение при попытке сохранить данные с localStorage.setItem() .

чтобы исправить это, я написал поддельный localStorage, который имитирует localStorage, как методы, так и события.

поддельные localStorage:https://gist.github.com/engelfrost/fd707819658f72b42f55

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

обновление (2016-11-01)

я использовал AmplifyJS, упомянутый ниже, чтобы обойти эту проблему. Однако для Safari в частном просмотре он возвращался к хранилищу на основе памяти. В моем случае это было неуместно, потому что это означает, что хранилище очищается при обновлении, даже если пользователь все еще находится в частном просмотре.

кроме того, я заметил ряд пользователей, которые всегда просматривают в частном режиме на iOS Safari. По этой причине лучшим резервным вариантом для Safari является используйте файлы cookie (если они доступны). По умолчанию куки-файлы по-прежнему доступны даже в приватном просмотре. Конечно, они очищаются при выходе из приватного просмотра, но они не очищаются при обновлении.

нашел локальные хранения запасной вариант библиотека. Из документации:

цель

с настройками браузера, такими как" частный просмотр", стало проблемой полагаться на рабочее окно.хранилище localStorage, даже в новых браузерах. Даже хотя он может существовать, он будет выдавать исключения при попытке использовать setItem или getItem. Этот модуль выполнит соответствующие проверки, чтобы увидеть, какой механизм хранения браузера может быть доступен, а затем предоставить его. Он использует тот же API, что и localStorage, поэтому в большинстве случаев он должен работать как замена drop-in.

остерегайтесь gotchas:

  • CookieStorage имеет ограничения по хранению. Будь осторожен здесь.
  • MemoryStorage не будет сохраняться между загрузка страниц. Это более или менее стоп-гэп для предотвращения сбоев страницы, но может быть достаточно для веб-сайтов, которые не выполняют полную загрузку страницы.

TL; DR:

использовать локальные хранения запасной вариант (унифицированный API с .getItem(prop) и .setItem(prop, val)):

проверьте и используйте соответствующий адаптер хранения для браузера (localStorage, sessionStorage, cookies, память)

оригинальный ответ

добавить по предыдущему ответы, одним из возможных обходных путей было бы изменить метод хранения. Есть несколько библиотек, таких как AmplifyJS и PersistJS, который может помочь. Обе библиотеки позволяют постоянное хранение на стороне клиента через несколько бэкэндов.

Для AmplifyJS

localStorage

  • IE 8+
  • Firefox 3.5+
  • Safari 4+
  • Chrome
  • Opera 10.5+
  • iPhone 2+
  • Android 2+

sessionStorage

  • IE 8+
  • Firefox 2+
  • Safari 4+
  • Chrome
  • Opera 10.5+
  • iPhone 2+
  • Android 2+

globalStorage

  • Firefox 2+

userData

  • т. е. 5 - 7
  • userData существует и в более новых версиях IE, но из-за причуд в реализации IE 9 мы не регистрируем userData, если localStorage поддерживаемый.

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

Для PersistentJS

  • вспышка: вспышка 8 постоянного хранения.
  • шестерни: Google Постоянное хранение на основе шестеренок.
  • localstorage: хранение проекта HTML5.
  • globalstorage: HTML5 draft storage (старая спецификация).
  • ie: поведение пользователя Internet Explorer.
  • cookie: постоянное хранилище на основе файлов Cookie.

они предлагают уровень абстракции, поэтому вам не придется беспокоиться о выборе типа склада. Имейте в виду, что могут быть некоторые ограничения (например, ограничения по размеру) в зависимости от однако тип хранения. Прямо сейчас я использую AmplifyJS, но мне все еще нужно сделать еще несколько тестов на iOS 7/Safari/etc. чтобы увидеть, действительно ли это решает проблему.

в апреле 2017 года патч был объединен в Safari, поэтому он выровнялся с другими браузерами. Это было выпущено с Safari 11.

https://bugs.webkit.org/show_bug.cgi?id=157010

этот вопрос и ответ помог мне решить конкретную проблему с регистрацией новых пользователей в Parse.

поскольку функция регистрации (attrs, options) использует локальное хранилище для сохранения сеанса, если пользователь находится в режиме приватного просмотра, он выдает "QuotaExceededError: DOM исключение 22: была сделана попытка добавить что-то в хранилище, которое превысило квоту."исключение и функции успеха/ошибки никогда не вызываются.

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

в том числе предупреждение для пользователей решен вопрос.

Parse Javascript SDK Reference https://parse.com/docs/js/api/classes/Parse.User.html#methods_signUp

регистрирует нового пользователя с именем пользователя (или электронной почтой) и паролем. Это создаст новый синтаксический анализ.Пользователь на сервере, а также сохранить сеанс в localStorage так что вы можете получить доступ к пользователю с помощью {@link #current}.

Comments

    Ничего не найдено.