it-swarm.com.de

QuotaExceededError: Dom-Ausnahme 22: Es wurde versucht, dem Speicher etwas hinzuzufügen, das das Kontingent überschreitet

Die Verwendung von LocalStorage auf dem iPhone mit iOS 7 löst diesen Fehler aus. Ich habe mich nach einer Lösung umgesehen, aber wenn ich nicht einmal privat surfe, ist nichts relevant.

Ich verstehe nicht, warum localStorage in iOS 7 standardmäßig deaktiviert ist, aber wie es scheint? Ich habe auch auf anderen Websites getestet, aber ohne Glück. Ich habe sogar versucht, es mit dieser Website zu testen: http://arty.name/localstorage.html , aber es scheint nicht, dass es aus irgendeinem seltsamen Grund überhaupt etwas spart.

Hat jemand das gleiche Problem gehabt, nur hatten sie das Glück, es zu beheben? Sollte ich meine Speichermethode ändern?

Ich habe versucht, das Problem zu beheben, indem ich nur ein paar Zeilen mit Informationen gespeichert habe, aber ohne Erfolg. Ich habe die Standardfunktion localStorage.setItem() zum Speichern verwendet.

216
NicT

Dies kann auftreten, wenn sich Safari im privaten Modus befindet. Beim privaten Surfen ist der lokale Speicher überhaupt nicht verfügbar.

Eine Lösung besteht darin, den Benutzer zu warnen, dass die App einen nicht privaten Modus benötigt, um zu funktionieren.

UPDATE: Dies wurde in Safari 11 behoben, so dass das Verhalten jetzt mit anderen Browsern abgeglichen ist.

365
Cristian Dinu

Wie in anderen Antworten erwähnt, erhalten Sie den QuotaExceededError immer im Safari Private Browser-Modus unter iOS und OS X, wenn localStorage.setItem (oder sessionStorage.setItem) wird genannt.

Eine Lösung besteht darin, ein try/catch oder Modernizr check in jedem Fall der Verwendung von setItem auszuführen.

Wenn Sie jedoch einen Shim möchten, der diesen Fehler einfach global verhindert, damit der Rest Ihres JavaScript nicht kaputt geht, können Sie Folgendes verwenden:

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.');
    }
}
103
philfreo

Ich benutze diese einfache Funktion, die true oder false zurückgibt, um die Verfügbarkeit von localStorage zu testen:

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

Jetzt können Sie die Verfügbarkeit von localStorage.setItem() testen, bevor Sie sie verwenden. Beispiel:

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

Ich lief zufällig mit dem gleichen Problem in iOS 7 (bei einigen Geräten keine Simulatoren).

Sieht so aus, als hätte Safari in iOS 7 ein geringeres Speicherkontingent, was anscheinend durch ein langes Verlaufsprotokoll erreicht wird.

Ich denke, die beste Praxis wird es sein, die Ausnahme zu fangen.

Das Modernizr-Projekt hat einen einfachen Patch, Sie sollten etwas Ähnliches ausprobieren: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js

5
defvol

Hier ist eine erweiterte Lösung, die auf der obigen Antwort von DrewT basiert und Cookies verwendet, wenn localStorage nicht verfügbar ist. Es verwendet Mozillas docCookies Bibliothek :

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;
}

Verwenden Sie in Ihrer Quelle einfach:

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

Update (01.11.2016)

Ich habe AmplifyJS verwendet, um dieses Problem zu umgehen. Für Safari beim privaten Surfen wurde jedoch auf einen speicherbasierten Speicher zurückgegriffen. In meinem Fall war dies nicht angemessen, da der Speicher beim Aktualisieren gelöscht wird, selbst wenn sich der Benutzer noch im privaten Browsing befindet.

Außerdem sind mir einige Benutzer aufgefallen, die unter iOS Safari immer im privaten Modus surfen. Aus diesem Grund ist ein besserer Fallback für Safari die Verwendung von Cookies (sofern verfügbar). Standardmäßig sind Cookies auch beim privaten Browsen weiterhin verfügbar. Natürlich werden sie beim Verlassen des privaten Browsers gelöscht, aber beim Aktualisieren nicht.

Ich habe die local-storage-fallback Bibliothek gefunden. Aus der Dokumentation:

Zweck

Mit Browsereinstellungen wie "Privates Browsen" ist es zu einem Problem geworden, sich auf ein funktionierendes window.localStorage zu verlassen, selbst in neueren Browsern. Auch wenn es existiert, löst es bei der Verwendung von setItem oder getItem Ausnahmen aus. Dieses Modul führt entsprechende Überprüfungen durch, um festzustellen, welcher Browser-Speichermechanismus verfügbar sein könnte, und macht ihn dann verfügbar. Es verwendet dieselbe API wie localStorage und sollte daher in den meisten Fällen als Ersatz dienen.

Vorsicht vor den Fallstricken:

  • Für CookieStorage gelten Speicherbeschränkungen. Sei hier vorsichtig.
  • MemoryStorage wird zwischen den Seitenladevorgängen nicht beibehalten. Dies ist mehr oder weniger eine Lücke, um Seitenabstürze zu verhindern, kann jedoch für Websites ausreichen, die keine vollständigen Seiten laden.

TL; DR:

Verwenden Sie local-storage-fallback (einheitliche API mit .getItem(prop) und .setItem(prop, val)):

Überprüfen und verwenden Sie den entsprechenden Speicheradapter für den Browser (localStorage, sessionStorage, Cookies, Speicher).

Ursprüngliche Antwort

Eine mögliche Problemumgehung besteht darin, die Speichermethode zu ändern, um frühere Antworten hinzuzufügen. Es gibt ein paar Bibliotheken wie AmplifyJS und PersistJS , die helfen können. Beide Bibliotheken ermöglichen eine dauerhafte clientseitige Speicherung über mehrere Backends.

Für AmplifyJS

lokaler Speicher

  • 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+

benutzerdaten

  • IE 5 - 7
  • userData ist auch in neueren Versionen von IE vorhanden, aber aufgrund von Fehlern in der Implementierung von IE= 9 werden userData nicht registriert, wenn localStorage unterstützt wird.

erinnerung

  • Ein In-Memory-Speicher wird als Fallback bereitgestellt, wenn keiner der anderen Speichertypen verfügbar ist.

Für PersistentJS

  • flash: Permanenter Flash 8-Speicher.
  • zahnräder: Google Gears-basierter permanenter Speicher.
  • localstorage: HTML5-Entwurfsspeicher.
  • globalstorage: HTML5-Entwurfsspeicher (alte Spezifikation).
  • dh: Internet Explorer-Benutzerdatenverhalten.
  • cookie: Cookie-basierter permanenter Speicher.

Sie bieten eine Abstraktionsschicht, sodass Sie sich keine Gedanken über die Auswahl des Speichertyps machen müssen. Beachten Sie jedoch, dass es je nach Speichertyp einige Einschränkungen (z. B. Größenbeschränkungen) geben kann. Im Moment benutze ich AmplifyJS, aber ich muss noch einige Tests unter iOS 7/Safari/etc durchführen. um zu sehen, ob es das Problem tatsächlich löst.

2

Wie bereits in anderen Antworten erläutert, wird im privaten Browsermodus Safari immer Diese Ausnahme wird ausgelöst, wenn versucht wird, Daten mit localStorage.setItem() zu speichern.

Um dies zu beheben, habe ich ein falsches localStorage geschrieben, das localStorage nachahmt, sowohl Methoden als auch Ereignisse.

Gefälschte lokale Speicherung: https://Gist.github.com/engelfrost/fd707819658f72b42f55

Dies ist wahrscheinlich keine gute allgemeine Lösung für das Problem. Dies war eine gute Lösung für mein Szenario, in dem die Alternative darin bestand, eine bereits vorhandene Anwendung grundlegend umzuschreiben.

2

Im April 2017 wurde ein Patch in Safari integriert, der mit den anderen Browsern abgeglichen wurde. Dies wurde mit Safari 11 veröffentlicht.

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

1
sandstrom

Diese Frage und Antwort hat mir geholfen, ein bestimmtes Problem bei der Registrierung neuer Benutzer in Parse zu lösen.

Da die signUp-Funktion (attrs, options) den lokalen Speicher verwendet, um die Sitzung beizubehalten, wird bei einem Benutzer im privaten Browsermodus die Meldung "QuotaExceededError: DOM Exception 22: Es wurde versucht, dem Speicher etwas hinzuzufügen, das das Kontingent überschreitet." Ausnahme und die Erfolgs-/Fehlerfunktionen werden nie aufgerufen.

In meinem Fall schien es, da die Fehlerfunktion nie aufgerufen wird, zunächst ein Problem mit dem Auslösen des Klickereignisses auf die Übermittlung oder der bei Erfolg der Anmeldung definierten Umleitung zu sein.

Einschließlich einer Warnung für Benutzer wurde das Problem behoben.

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

Registrieren Sie einen neuen Benutzer mit einem Benutzernamen (oder einer E-Mail-Adresse) und einem Passwort. Dadurch wird ein neuer Parse.User auf dem Server erstellt und die Sitzung in localStorage beibehalten , sodass Sie mit {@link #current auf den Benutzer zugreifen können }.

0
clayostrom