Überprüfen Sie, ob localStorage verfügbar ist

78

Ich weiß, es gab viele Fragen zum Überprüfen, localStorageaber was ist, wenn jemand es manuell in seinem Browser ausschaltet? Hier ist der Code, mit dem ich überprüfe:

localStorage.setItem('mod', 'mod');
if (localStorage.getItem('mod') != null){
  alert ('yes');
  localStorage.removeItem('mod');
} else {
  alert ('no');
}

Einfache Funktion und es funktioniert. Wenn ich jedoch in meine Chrome-Einstellungen gehe und die Option "Daten nicht speichern" wähle (ich erinnere mich nicht genau, wie sie heißt), erhalte ich beim Ausführen dieser Funktion nur Uncaught Error: SecurityError: DOM Exception 18. Gibt es also eine Möglichkeit zu überprüfen, ob die Person es vollständig ausgeschaltet hat?

UPDATE: Dies ist die zweite Funktion, die ich ausprobiert habe, und ich erhalte immer noch keine Antwort (Warnung).

try {
  localStorage.setItem('name', 'Hello World!');
} catch (e) {
  if (e == QUOTA_EXCEEDED_ERR) {
   alert('Quota exceeded!');
  }
}
user2025469
quelle
bietet immer noch keine Möglichkeit zu sehen, ob es funktioniert oder nicht ...
user2025469
6
Uhhhhmmm. Wenn es eine Ausnahme
auslöst,
2
Mögliches Duplikat von Check for HTML 5 localStorage
BuZZ-dEE

Antworten:

128

Verwenden Sie modernizrden Ansatz von (vielleicht möchten Sie meinen Funktionsnamen in etwas Besseres ändern):

function lsTest(){
    var test = 'test';
    try {
        localStorage.setItem(test, test);
        localStorage.removeItem(test);
        return true;
    } catch(e) {
        return false;
    }
}

if(lsTest() === true){
    // available
}else{
    // unavailable
}

Es ist nicht so präzise wie andere Methoden, aber das liegt daran, dass es die Kompatibilität maximiert.

Die ursprüngliche Quelle: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js

Arbeitsbeispiel: http://jsfiddle.net/6sm54/2/

Joe
quelle
1
Hey Joe, ich bekomme diesen Fehler beim Ausführen Ihrer Funktion (LS ein- oder ausgeschaltet) "Ungefangener Syntaxfehler: Unzulässige Rückgabeanweisung"
user2025469
1
@ user2025469 Dieser Code sollte als Funktion verwendet werden.
Kiruse
1
Entschuldigung, ich hätte das erwähnen sollen. Ich habe meine Antwort aktualisiert und eine Demo hinzugefügt, damit Sie sehen können, dass sie ordnungsgemäß funktioniert.
Joe
1
Joe, genau das habe ich gesucht. Wenn ich LS ausschalte, sind keine Warnungen verfügbar. Ist dies nur eine grundlegende Javascript-Funktion oder muss ich das modernizr JS in mein Skript aufnehmen>
user2025469
7
IN ACHT NEHMEN! Dieser Modernizr-Ansatz gibt false zurück, wenn das localStorage-Kontingent erreicht ist. Wenn Sie Funktionen haben, die sich mit der Bereinigung von localStorage befassen, sollten Sie die catch-Anweisung bearbeiten, um geeignete Bereinigungsaktionen zu starten, wenn der Ausnahmenname e.name ==== 'QUOTA_EXCEEDED_ERR'(Chrome) oder 'NS_ERROR_DOM_QUOTA_REACHED'(Firefox / Safari) oder localStorage.remainingSpace === 0im IE vorhanden ist.
KrisWebDev
24

Ich würde überprüfen, ob dies localStoragedefiniert ist, bevor eine Aktion davon abhängt:

if (typeof localStorage !== 'undefined') {
    var x = localStorage.getItem('mod');
} else {
    // localStorage not defined
}

AKTUALISIEREN:

Wenn Sie überprüfen müssen, ob die Funktion vorhanden ist und auch nicht deaktiviert ist, müssen Sie einen sichereren Ansatz verwenden. Um ganz sicher zu gehen:

if (typeof localStorage !== 'undefined') {
    try {
        localStorage.setItem('feature_test', 'yes');
        if (localStorage.getItem('feature_test') === 'yes') {
            localStorage.removeItem('feature_test');
            // localStorage is enabled
        } else {
            // localStorage is disabled
        }
    } catch(e) {
        // localStorage is disabled
    }
} else {
    // localStorage is not available
}
Frederik.L
quelle
1
Unter den gegebenen Umständen ist dies nur eine Funktion, die verhindert, dass andere Browser Fehler machen. Dies beantwortet die Frage also nicht wirklich. Wenn ausgeschaltet, wird localStorageimmer noch in definiert window.
Kiruse
1
Sie erhalten immer noch einen DOM-Fehler ... Ich kann einfach nicht glauben, dass es keine Möglichkeit gibt, zu überprüfen, ob es vollständig ausgeschaltet ist ...
user2025469
2
Dies ist kein sicherer Ansatz für Chrome und Opera ... wahrscheinlich auch nicht für Safari, da nicht localStoragevollständig darauf zugegriffen werden kann und eine Ausnahme ausgelöst wird.
Shikkediel
Sie brauchen nicht alle diese elses ... Nur ein einziger Versuch sollte reichen. Ich sehe, dass Sie testen, ob das Ergebnis tatsächlich ist 'yes', aber ich habe keinen Anwendungsfall, in dem dies tatsächlich notwendig ist.
Stijn de Witt
11

Das Erkennen von lokalem Speicher mit Funktionen ist schwierig. Sie müssen tatsächlich hinein greifen. Der Grund dafür ist, dass Safari beschlossen hat, ein Funktionsobjekt localStorageim privaten Modus anzubieten , dessen Quotum jedoch auf Null gesetzt ist . Dies bedeutet, dass, obwohl alle einfachen Funktionserkennungen erfolgreich sind, alle Aufrufe von localStorage.setItemeine Ausnahme auslösen.

Der Mozilla Developer Network-Eintrag in den Web Storage-APIs enthält einen eigenen Abschnitt zum Erkennen von lokalem Speicher . Hier ist die auf dieser Seite empfohlene Methode:

function storageAvailable(type) {
    try {
        var storage = window[type],
            x = '__storage_test__';
        storage.setItem(x, x);
        storage.removeItem(x);
        return true;
    }
    catch(e) {
        return false;
    }
}

Und so würden Sie es verwenden:

if (storageAvailable('localStorage')) {
    // Yippee! We can use localStorage awesomeness
}
else {
    // Too bad, no localStorage for us
}

Wenn Sie NPM verwenden, können Sie greifen Speicher verfügbar mit

npm install -S storage-available

Verwenden Sie dann die folgende Funktion:

if (require('storage-available')('localStorage')) {
    // Yippee! We can use localStorage awesomeness
}

Haftungsausschluss : Sowohl der Dokumentationsabschnitt zu MDN als auch das NPM-Paket wurden von mir verfasst.

Stijn de Witt
quelle
5

MDN hat die Speichererkennungsfunktion aktualisiert . Im Jahr 2018 ist es zuverlässiger:

function storageAvailable() {
    try {
        var storage = window['localStorage'],
            x = '__storage_test__';
        storage.setItem(x, x);
        storage.removeItem(x);
        return true;
    }
    catch(e) {
        return e instanceof DOMException && (
            // everything except Firefox
            e.code === 22 ||
            // Firefox
            e.code === 1014 ||
            // test name field too, because code might not be present
            // everything except Firefox
            e.name === 'QuotaExceededError' ||
            // Firefox
            e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
            // acknowledge QuotaExceededError only if there's something already stored
            storage && storage.length !== 0;
    }
}

Browser, die localStorage unterstützen, haben eine Eigenschaft für das Fensterobjekt mit dem Namen localStorage. Aus verschiedenen Gründen kann es jedoch Ausnahmen geben, wenn nur behauptet wird, dass eine Eigenschaft vorhanden ist. Wenn es existiert, ist dies immer noch keine Garantie dafür, dass localStorage tatsächlich verfügbar ist, da verschiedene Browser Einstellungen anbieten, die localStorage deaktivieren. So ein Browser kann unterstützen local, aber nicht machen verfügbar zu den Skripts auf der Seite. Ein Beispiel hierfür ist Safari, bei dem im privaten Browsermodus ein leeres localStorage-Objekt mit einem Kontingent von Null angezeigt wird, wodurch es effektiv unbrauchbar wird. Möglicherweise erhalten wir jedoch weiterhin einen legitimen QuotaExceededError. Dies bedeutet nur, dass wir den gesamten verfügbaren Speicherplatz verbraucht haben, der Speicher jedoch tatsächlich verfügbar ist . Unsere Feature-Erkennung sollte diese Szenarien berücksichtigen.

Hier finden Sie eine kurze Historie zur Erkennung von Merkmalen localStorage .

mcmimik
quelle
Dies ist nicht das genaue Verhalten, das ich in Safari mit iOS 12.1 sehe. Ich kann Dinge festlegen und abrufen - sie bleiben einfach nicht bestehen, nachdem ich diese Registerkarte geschlossen habe. Selbst wenn ich eine andere Website auf derselben Registerkarte besuche und zurückkomme, sind meine gespeicherten Daten immer noch da. Also nicht sicher, wie alt dieser Kommentar ist.
Simon_Weaver
Anscheinend war es ein Fehler, der seitdem behoben wurde - stackoverflow.com/questions/14555347/… . Sie müssen davon ausgehen, dass Ihre Benutzer im privaten Modus voraussichtlich die Sitzung verlieren, wenn sie weggehen und zurückkehren.
Simon_Weaver
This isn't the exact behavior I'm seeing in Safari with iOS 12.1. I'm able to set things and retrieve them - they just don't persist after I close that tab. Ja. Zum Glück wurden die WebKit-Entwickler schlau und änderten das fehlerhafte Verhalten. In alten Versionen werfen sie Quotenüberschreitungsfehler aus und versuchen, im privaten Modus in localStorage zu schreiben. Dies ist unerwartet und hat den Entwicklern viele Probleme bereitet. In späteren Versionen haben sie es geändert, um es an das Verhalten anderer Browser und Cookies anzupassen: Es funktioniert, aber nur solange der Browser geöffnet bleibt.
Stijn de Witt
Ich erhalte keine Fehlermeldung, wenn ich versuche, aus dem lokalen Speicher zu schreiben oder zu lesen, während ich den privaten Safari-Modus auf Mobilgeräten verwende. Safari wird einfach nichts tun und lautlos scheitern.
SomewhereDave
0

Mit dieser Funktion können Sie prüfen, ob localstorage verfügbar ist oder nicht, und die möglichen Ausnahmen unter Kontrolle halten.

function isLocalStorageAvailable() {

    try {
        var valueToStore = 'test';
        var mykey = 'key';
        localStorage.setItem(mykey, valueToStore);
        var recoveredValue = localStorage.getItem(mykey);
        localStorage.removeItem(mykey);

        return recoveredValue === valueToStore;
    } catch(e) {
        return false;
    }
}
Luis Moyano
quelle
-1

Das Ändern von Joes Antwort, um einen Getter hinzuzufügen, erleichtert die Verwendung. Mit dem Folgenden sagen Sie einfach:if(ls)...

Object.defineProperty(this, "ls", {
  get: function () { 
    var test = 'test';
    try {
      localStorage.setItem(test, test);
      localStorage.removeItem(test);
      return true;
    } catch(e) {
      return false;
    }
  }
});
Ronnie Royston
quelle
Warum das Downvote? Es funktioniert und das Tippen lsist besser als das Tippen lsTest() === true. ...?
Ronnie Royston
Es funktioniert nicht. Sie weisen ls... ein Objekt zu, das als solches if (ls)immer ausgewertet wird true. Überprüfen Sie es einfach, indem Sie Ihre getMethode auf Lesen ändern , get: function(){return false}und Sie werden sehen. Außerdem ist das Tippen lsnicht besser ... Dieser Test wird nicht zu oft in Ihrem Code enthalten sein (wenn Sie ihn auf intelligente Weise schreiben). Warum sollten Sie also den (globalen) Bereich mit einer sehr kurzen Variablen verschmutzen?
Stijn de Witt
Ihr Recht. Ich muss das reparieren ... Danke!
Ronnie Royston
@StijndeWitt es funktioniert jetzt. Vielen Dank für Ihr Feedback ... In Bezug auf die Verschmutzung des globalen Geltungsbereichs verstehe ich Ihren Standpunkt, aber ich denke, das ist eine Meinung. Jemand könnte feststellen, dass sich das Tippen if(ls){...lohnt.
Ronnie Royston
-2

Hier ist eine einfache Überprüfung:

if(typeof localStorage === 'undefined'){

Brady
quelle
5
Die Art der localStorageRückgabe object, auch wenn sie in Firefox oder IE deaktiviert ist. In Chrome und Opera typeoflöst eine Ausnahme aus und bricht das gesamte Skript, wenn der Benutzer es
deaktiviert
Und in Safari im privaten Browsermodus erhalten Sie ein Arbeitsobjekt localStoragemit einem Kontingent von Null und lösen daher eine Ausnahme aus, wenn Sie versuchen, darauf zu schreiben. Aus diesem Grund versucht die lokale Speicherfunktion, die jetzt Code erkennt, immer, ein Element zu schreiben.
Stijn de Witt
-3

Verwenden Sie diese Option, um zu überprüfen, ob localStorage festgelegt ist oder nicht. Es hilft Ihnen, den Status von Localstorage zu erhalten.

    if( window.localStorage.fullName !== undefined){

           //action
   }else{
          }
Lucky W.
quelle
4
Sie müssen nicht warten, bis das Dokument geladen ist, um auf localStorage zuzugreifen ( $()ist also sinnlos). Noch wichtiger ist, dass dieser Code einen Fehler auslöst, wenn localStorage nicht verfügbar ist.
1j01
Tatsächlich geben Mozilla-Dokumente einen localStoragesynchronen Status an, sodass das Rendern des Hauptdokuments blockiert werden kann. Es wäre daher ein guter Ansatz, darauf zu warten, dass es fertig ist.
Shikkediel
Was sie damit meinen, dass sie localStoragesynchron sind, ist, dass localStorage.getItem('someKey')der Artikel tatsächlich sofort zurückgegeben wird. Es akzeptiert keine Rückruffunktion oder gibt a zurück Promise, sondern gibt die Daten sofort zurück. Vergleichen Sie das mit zB var result = fetch('https://example.com/data.json')... das gibt a zurück Promise, was es asynchron macht. Sie müssen die thenMethode aufrufen , um an die Daten zu gelangen (wird nur beim nächsten Tick auftreten):result.then(function(data){ /* only here do we get the data */ })
Stijn de Witt
Es geht um die Tatsache, dass synchrone Aufrufe das Rendern blockieren und das weitere Parsen der Seite unterbrechen. Rückrufverhalten ist hier eher irrelevant.
Shikkediel