Quotaexceedederror: Dom wyjątek 22: podjęto próbę dodania do magazynu czegoś, co przekroczyło limit

Używanie LocalStorage na iPhonie z iOS 7 powoduje ten błąd. Rozglądałem się za zdecydowanym, ale biorąc pod uwagę, że nawet nie przeglądam prywatnie, nic nie jest istotne.

Nie rozumiem, dlaczego localStorage byłby domyślnie wyłączony w iOS 7, ale wygląda na to, że tak jest? Testowałem również na innych stronach internetowych, ale bez powodzenia. Próbowałem nawet przetestować go za pomocą tej strony: http://arty.name/localstorage.html , ale wydaje się, że nie oszczędza niczego dla niektórych dziwny powód.

Czy ktoś miał ten sam problem, tylko że miał szczęście go naprawić? Czy powinienem zmienić metodę przechowywania?

Próbowałem go dokładnie debugować, przechowując tylko kilka linii informacji, ale bezskutecznie. Do zapisu użyłem standardowej funkcji localStorage.setItem().

Author: NicT, 2014-01-16

9 answers

Może się to zdarzyć, gdy przeglądanie Safari jest w trybie prywatnym. Podczas przeglądania prywatnego pamięć lokalna nie jest w ogóle dostępna.

Jednym z rozwiązań jest Ostrzeżenie użytkownika, że aplikacja potrzebuje trybu non-private do pracy.

Aktualizacja: to zostało naprawione w Safari 11, więc zachowanie jest teraz wyrównane z innymi przeglądarkami.

 347
Author: Cristian Dinu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-20 12:39:54

Jak wspomniano w innych odpowiedziach, zawsze otrzymasz QuotaExceededError w trybie przeglądarki prywatnej Safari zarówno na iOS, jak i OS X po wywołaniu localStorage.setItem (lub sessionStorage.setItem).

Jednym z rozwiązań jest wykonanie try / catch lub Modernizr check w każdym przypadku użycia setItem.

Jeśli jednak chcesz podkładkę, która po prostu globalnie zatrzymuje ten błąd, aby zapobiec łamaniu reszty JavaScript, możesz użyć to:

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.');
    }
}
 102
Author: philfreo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-22 19:16:05

Używam tej prostej funkcji, która zwraca true lub false, aby przetestować dostępność localStorage:

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

Teraz możesz przetestować dostępność localStorage.setItem() przed użyciem. Przykład:

if ( isLocalStorageNameSupported() ) {
    // can use localStorage.setItem('item','value')
} else {
    // can't use localStorage.setItem('item','value')
}
 16
Author: DrewT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-11 18:07:24

Zdarzyło mi się uruchomić z tym samym problemem w iOS 7 (z niektórymi urządzeniami bez symulatorów).

Wygląda na to, że Safari w iOS 7 ma niższy limit pamięci, który najwyraźniej osiąga się poprzez posiadanie długiego dziennika historii.

Myślę, że najlepszą praktyką będzie złapanie wyjątku.

Projekt Modernizr ma łatkę, powinieneś spróbować czegoś podobnego: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js

 5
Author: rodowi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-13 00:30:00

Oto rozszerzone rozwiązanie oparte na powyższej odpowiedzi DrewT, które wykorzystuje pliki cookie, jeśli localStorage nie jest dostępna. Używa biblioteki Mozilli 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;
}

W Twoim źródle po prostu użyj:

localStorageSet( 'foobar', 'yes' );
...
var foo = localStorageGet( 'foobar' );
...
 3
Author: Stickley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-08 17:11:54

Jak już wyjaśniono w innych odpowiedziach, Podczas przeglądania prywatnego Safari będzie Zawsze rzucać ten wyjątek podczas próby zapisania danych za pomocą localStorage.setItem() .

Aby to naprawić, napisałem fałszywą localStorage, która naśladuje localStorage, zarówno metody, jak i zdarzenia.

Fake localStorage: https://gist.github.com/engelfrost/fd707819658f72b42f55

prawdopodobnie nie jest to dobre ogólne rozwiązanie problemu. To było dobre rozwiązanie dla mojego scenariusza, gdzie alternatywą byłoby poważne ponowne zapisanie do już istniejącej aplikacji.

 2
Author: Josef Engelfrost,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-01 11:21:30

Aktualizacja (2016-11-01)

Używałem AmplifyJS wymienionych poniżej, aby obejść ten problem. Jednak w przypadku Safari w przeglądaniu prywatnym powracało do pamięci masowej opartej na pamięci. W moim przypadku nie było to właściwe, ponieważ oznacza to, że pamięć jest wyczyszczona przy odświeżaniu, nawet jeśli użytkownik jest nadal w przeglądaniu prywatnym.

Zauważyłem również wielu użytkowników, którzy zawsze przeglądają w trybie prywatnym na iOS Safari. Z tego powodu lepszym rozwiązaniem dla Safari jest użycie plików cookie (jeśli dostępne). Domyślnie pliki cookie są nadal dostępne nawet podczas przeglądania prywatnego. Oczywiście są one czyszczone po zakończeniu przeglądania prywatnego, ale nie są czyszczone przy odświeżaniu.

Znalazłem bibliotekęlocal-storage-fallback . Z dokumentacji:

Cel

Z ustawieniami przeglądarki, takimi jak" Przeglądanie prywatne", stało się problemem poleganie na działającym oknie.localStorage, nawet w nowszych przeglądarkach. Choć może istnieć, rzuci wyjątki podczas próby użycia setItem lub getItem. Moduł ten przeprowadzi odpowiednie kontrole, aby sprawdzić, jaki mechanizm przechowywania przeglądarki może być dostępny, a następnie go ujawnić. Używa tego samego API co localStorage, więc w większości przypadków powinien działać jako zamiennik drop-in.

Uwaga na gotchów:

  • CookieStorage ma ograniczenia przechowywania. Ostrożnie.
  • MemoryStorage nie będzie się utrzymywać pomiędzy ładowaniem stron. Jest to mniej więcej stop-gap, aby zapobiec stronie awaria, ale może być wystarczająca dla witryn, które nie ładują całych stron.

TL; DR:

Użyj local-storage-fallback (unified API with .getItem(prop) and .setItem(prop, val)):

Sprawdź i użyj odpowiedniego adaptera pamięci dla przeglądarki (localStorage, sessionStorage, cookies, memory)

Oryginalna odpowiedź

Aby dodać poprzednie odpowiedzi, jednym z możliwych obejść byłaby zmiana metody przechowywania. Istnieje kilka bibliotek, takich jak AmplifyJS i PersistJS które mogą pomóc. Obie biblioteki umożliwiają trwałe przechowywanie po stronie klienta poprzez kilka backendów.

Dla 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

  • IE 5-7
  • userData istnieje również w nowszych wersjach IE, ale ze względu na dziwactwa w implementacji IE 9, nie rejestrujemy userData, jeśli localStorage jest obsługiwana.

Pamięć

  • magazyn w pamięci jest dostarczany jako zapasowy, jeśli żaden z innych dostępne są typy pamięci.

For PersistentJS

  • flash: Flash 8
  • gears: trwała pamięć masowa oparta na narzędziach Google.
  • localstorage: HTML5 draft storage.
  • globalstorage: HTML5 draft storage (stara Specyfikacja).
  • ie: zachowania danych Użytkownika w przeglądarce Internet Explorer.
  • cookie: trwałe przechowywanie oparte na plikach Cookie.

Oferują warstwę abstrakcji, więc nie musisz martw się o wybór rodzaju przechowywania. Pamiętaj jednak, że mogą istnieć pewne ograniczenia (takie jak limity rozmiaru) w zależności od typu pamięci masowej. W tej chwili używam AmplifyJS, ale nadal muszę wykonać kilka testów na iOS 7/Safari / itp. sprawdzić, czy to rzeczywiście rozwiąże problem.

 2
Author: Jonathan Alzetta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-05 08:51:10

W kwietniu 2017 roku łatka została scalona z Safari, więc dostosowała się do innych przeglądarek. Został wydany z Safari 11.

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

 1
Author: sandstrom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-20 12:37:51

To pytanie i odpowiedź pomogły mi rozwiązać konkretny problem z rejestracją nowych użytkowników w Parse.

Ponieważ funkcja signUp (attrs, options) używa pamięci lokalnej do utrzymywania sesji, jeśli użytkownik jest w trybie przeglądania prywatnego, rzuca " QuotaExceededError: DOM wyjątek 22: podjęto próbę dodania czegoś do pamięci, co przekroczyło limit."wyjątek i funkcje sukcesu/błędu nigdy nie są wywoływane.

W moim przypadku, ponieważ funkcja błędu nigdy nie jest wywoływana początkowo pojawił się problem z odpaleniem zdarzenia kliknięcia na submit lub przekierowania zdefiniowanego po pomyślnym zarejestrowaniu się.

Wraz z ostrzeżeniem dla użytkowników rozwiązał problem.

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

Rejestracja nowego Użytkownika z nazwą użytkownika (lub e-mail) i hasłem. Spowoduje to utworzenie nowego Parse.Użytkownika na serwerze, , a także persist sesji w localStorage , dzięki czemu można uzyskać dostęp do Użytkownika za pomocą {@link # current}.

 0
Author: clayostrom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-18 06:58:59