Wie lösche ich ein localStorage-Element, wenn das Browserfenster / die Registerkarte geschlossen ist?


403

Mein Fall: localStorage mit Schlüssel + Wert, der beim Schließen des Browsers gelöscht werden soll und keine einzelne Registerkarte.

Bitte sehen Sie meinen Code, ob er richtig ist und was verbessert werden kann:

//create localStorage key + value if not exist
if(localStorage){
   localStorage.myPageDataArr={"name"=>"Dan","lastname"=>"Bonny"}; 
}

//when browser closed - psedocode
$(window).unload(function(){
  localStorage.myPageDataArr=undefined;
});

32
Wenn Sie den lokalen Speicher beim Schließen des Browsers löschen möchten, würde ich Ihre Gründe für die Verwendung in Frage stellen.
Dunhamzzz

16
Sie können sowohl lokale als auch Sitzungsspeicherobjekte haben. Ich würde sessionStorage für Sitzungswerte verwenden. Übrigens: Wenn Sie einen Wert auf undefiniert setzen, wird er nicht gelöscht oder aus localStorage entfernt. Der Wert wird lediglich auf undefiniert gesetzt.
kennebec

2
@kennebec - Die Einstellung auf undefinedwürde das zuvor gespeicherte Element jedoch überschreiben. Aber ja, die Verwendung .removeItem()ist angemessener.
nnnnnn

2
Verwenden Sie einfach sessionStorage anstelle von localStorage
Alberto Acuña

2
Verwenden localStorage.clear(); Sie diese Option, wenn Sie den gesamten Speicher löschen möchten.
Black Mamba

Antworten:


802

sollte so gemacht werden und nicht mit dem Löschoperator:

localStorage.removeItem(key);

1
Warum können wir den Löschoperator nicht genau verwenden? Aus meinen Tests geht hervor, dass delete localStorage.keydas genauso gut funktioniert wie localStorage.removeItem(key). Es scheint mir klarer zu sein, delete zu verwenden, wenn ich meine Variablen localStorage.key = 1eher wie als setze localStorage.setItem('key', 1).
Aust

6
Wenn es funktioniert, können Sie es technisch verwenden. Angesichts der Tatsache, dass removeItem als Elementfunktion bereitgestellt wird, erscheint es logisch, es zu verwenden, anstatt mit einem separaten Operator auf potenziell undefiniertes Verhalten zu stoßen.
Kungphu

@kungphu denken Sie daran, dass man immer (aus Versehen) tun kann localStorage.removeItem = null;, um localStorage.removeItem(key);eine potenziell schlechte Idee zu machen.
skeggse

31
Ich sehe nicht ein, wie vernünftig es ist, dies zu planen. Die Tatsache, dass eine Sprache es Menschen ermöglicht, destruktive Dinge zu tun, bedeutet nicht, dass Sie nicht standardisierte Methoden anwenden sollten, um Bibliotheken als Schutz gegen den Missbrauch der Sprache zu verwenden. Wenn Sie oder Ihre Kollegen den Unterschied zwischen Aufruf und Zuweisung nicht verstehen, haben Sie viel größere Probleme als das Entfernen von Elementen aus localStorage.
Kungphu

3
@skeggse das ist genau der Grund, warum es eine schlechte Idee ist, überhaupt zu schreiben localStorage.key = 1- um diese Art von Unfällen zu vermeiden
Jivan

114

Verwendung mit windowglobalem Schlüsselwort: -

 window.localStorage.removeItem('keyName');

6
Warum Windows Object verwenden? localStorage.removeItem(key)funktioniert einfach gut.
Pardeep Jain


Funktioniert diese Lösung wirklich für IE 11? Bitte vorschlagen. Ich habe dieses Problem im Winkel-5-Code.
Karan

95

Sie können das beforeunloadEreignis in JavaScript verwenden.

Mit Vanille-JavaScript können Sie Folgendes tun:

window.onbeforeunload = function() {
  localStorage.removeItem(key);
  return '';
};

Dadurch wird der Schlüssel gelöscht, bevor das Browserfenster / die Registerkarte geschlossen wird, und Sie werden aufgefordert, die Aktion zum Schließen des Fensters / der Registerkarte zu bestätigen. Ich hoffe das löst dein Problem.

HINWEIS: Die onbeforeunloadMethode sollte eine Zeichenfolge zurückgeben.


Das war in der Tat nützlich. Es könnte schön sein, die Antwort zu akzeptieren (auch nach all dieser Zeit).
Richard Morgan

8
@dhsto VanillaJS ist einfaches JavaScript :) Schau hier: Was ist VanillaJS? .
Bharat Khatri

1
Ein Problem besteht darin, dass dies auch dann aufgerufen wird, wenn Sie auf derselben Seite navigieren, nicht nur, wenn die Registerkarte geschlossen ist, was möglicherweise nicht beabsichtigt ist. Randnotiz: Wenn Sie undefiniert von onbeforeunload zurückgeben, wird die Meldung deaktiviert, die beim Entladen angezeigt wird.
Stan Bondi

Was ist passiert, wenn der Benutzer auf der Seite bleiben möchte und Sie den lokalen Speicher bereits löschen? Auch die Lösung funktioniert nicht auf Chrome und IE11
oracleruiz

Warum dann nicht sessionStorage verwenden?
Sachin Prasad

94

Sie sollten stattdessen den sessionStorage verwenden, wenn der Schlüssel beim Schließen des Browsers gelöscht werden soll.


3
Dies ist die beste Antwort; sessionStorageist das Mittel gegen das, was der Fragesteller beschreibt.
Benny

8
+1 für die Erwähnung sessionStorage, aber im Entwurf des W3C-Editors heißt es: "Die Lebensdauer eines Browserkontexts kann nicht mit der Lebensdauer des eigentlichen Benutzeragentenprozesses selbst zusammenhängen, da der Benutzeragent möglicherweise die Wiederaufnahme von Sitzungen nach einem Neustart unterstützt."
Tamás

28
Das Problem mit 'sessionStorage' ist, dass es nicht gespeichert wird, wenn Sie eine neue Registerkarte öffnen, z. B. wenn Sie bei gedrückter Strg-Taste auf einen Link klicken. Ich brauche einen localStorage / sessionStorage Hybrid lol.
Edwin Stoteler

3
@ EdwinStoteler Ich auch. Ich bin ein bisschen verwirrt, was sie dachten, als sie es so entworfen haben. Ich brauche wirklich Zugriff auf einen speicherinternen Browserspeicher, der beim Schließen des Browsers zerstört wird. Ich möchte vertrauliche Informationen so speichern, dass auf sie über eine gesamte Domäne zugegriffen werden kann, aber ich möchte nicht, dass diese Informationen auf Festplatten gelangen.
BT

19

Versuchen Sie es mit

$(window).unload(function(){
  localStorage.clear();
});

Hoffe das funktioniert bei dir


2
Möchten Sie den gesamten localStorage löschen? Wenn ja, verwenden Sie einfachlocalStorage.clear();
Rafael Marques

Es war klar, was ich in Frage stellen möchte - Schlüssel nur löschen + Wert
Josef

12
Dadurch wird der gesamte lokale Speicher aufgeräumt. schlechte Lösung!
Emmy

12

Es gibt einen sehr speziellen Anwendungsfall, in dem ein Vorschlag, sessionStorage anstelle von localStorage zu verwenden, nicht wirklich hilft. Der Anwendungsfall wäre so einfach wie das Speichern von etwas, während Sie mindestens eine Registerkarte geöffnet haben. Machen Sie es jedoch ungültig, wenn Sie die letzte verbleibende Registerkarte schließen. Wenn Sie möchten, dass Ihre Werte tabellen- und fensterübergreifend gespeichert werden, hilft Ihnen sessionStorage nur, wenn Sie Ihr Leben mit Zuhörern komplizieren, wie ich es versucht habe. In der Zwischenzeit wäre localStorage perfekt dafür, aber es macht den Job "zu gut", da Ihre Daten dort auch nach einem Neustart des Browsers warten. Am Ende habe ich einen benutzerdefinierten Code und eine Logik verwendet, die beide Vorteile nutzen.

Ich würde es lieber erklären und dann Code geben. Speichern Sie zuerst das, was Sie benötigen, in localStorage und erstellen Sie dann auch in localStorage einen Zähler, der die Anzahl der geöffneten Registerkarten enthält. Dies wird bei jedem Laden der Seite erhöht und bei jedem Entladen der Seite verringert. Sie können hier eine Auswahl der zu verwendenden Ereignisse treffen. Ich würde "Laden" und "Entladen" vorschlagen. Zum Zeitpunkt des Entladens müssen Sie die gewünschten Bereinigungsaufgaben ausführen, wenn der Zähler 0 erreicht. Dies bedeutet, dass Sie die letzte Registerkarte schließen. Hier kommt der schwierige Teil: Ich habe keinen zuverlässigen und allgemeinen Weg gefunden, um den Unterschied zwischen einem erneuten Laden oder Navigieren der Seite innerhalb der Seite und dem Schließen der Registerkarte zu erkennen. Wenn die von Ihnen gespeicherten Daten beim Laden nicht neu erstellt werden können, nachdem Sie überprüft haben, ob dies Ihre erste Registerkarte ist, dann können Sie es nicht bei jeder Aktualisierung entfernen. Stattdessen müssen Sie bei jedem Laden ein Flag in sessionStorage speichern, bevor Sie den Tabulatorzähler erhöhen. Bevor Sie diesen Wert speichern, können Sie überprüfen, ob er bereits einen Wert hat. Wenn dies nicht der Fall ist, bedeutet dies, dass Sie zum ersten Mal in diese Sitzung laden. In diesem Fall können Sie die Bereinigung beim Laden durchführen Wert ist nicht gesetzt und der Zähler ist 0.


Als Antwort auf die Frage "Warum nicht sessionStorage verwenden?" Ansatz, auch von w3schools.com/html/html5_webstorage.asp : "window.sessionStorage - speichert Daten für eine Sitzung (Daten gehen verloren, wenn die Registerkarte geschlossen wird)". Die Antwort ist also genau das. sessionStorage ist nutzlos, wenn Sie auch in dem von mir beschriebenen Anwendungsfall etwas Beständiges wollen.
Solthun

3
Ich denke, die beste Implementierung hierfür wäre ein browserWatcher-Dienst, der im Grunde genommen Ereignisse auslöst, die andere Komponenten abhören können (z. B. Browser öffnen, Browser schließen, Browser laden, Browser entladen usw.) und alle diese Implementierungsdetails darin verbirgt Jede Komponente kann entscheiden, welche Ereignisse sie verarbeiten muss, um ihre Arbeit zu erledigen. Meine einzige Frage wäre, was passiert, wenn die Stromversorgung der Maschine unterbrochen wird oder so, dann bleiben diese Eigenschaften beim nächsten Öffnen des Browsers in localStorage, nicht wahr? ?
pQuestions123

11

Verwenden Sie sessionStorage

Das sessionStorage-Objekt entspricht dem localStorage-Objekt, außer dass die Daten nur für eine Sitzung gespeichert werden. Die Daten werden gelöscht, wenn der Benutzer das Browserfenster schließt.

Im folgenden Beispiel wird gezählt, wie oft ein Benutzer in der aktuellen Sitzung auf eine Schaltfläche geklickt hat:

Beispiel

if (sessionStorage.clickcount) {
    sessionStorage.clickcount = Number(sessionStorage.clickcount) + 1;
} else {
    sessionStorage.clickcount = 1;
}
document.getElementById("result").innerHTML = "You have clicked the button " +
sessionStorage.clickcount + " time(s) in this session.";

1
Die Daten werden auf der Registerkarte Browser gelöscht.
Kosmonaft

7
for (let i = 0; i < localStorage.length; i++) {
    if (localStorage.key(i).indexOf('the-name-to-delete') > -1) {
        arr.push(localStorage.key(i));
    }
}

for (let i = 0; i < arr.length; i++) {
    localStorage.removeItem(arr[i]);
}

5
localStorage.removeItem(key);  //item

localStorage.clear(); //all items

1
Wenn Sie eine alte Frage beantworten, ist Ihre Antwort für andere StackOverflow-Benutzer viel nützlicher, wenn Sie einen Kontext angeben, um zu erklären, wie Ihre Antwort hilft, insbesondere für eine Frage, für die bereits eine Antwort akzeptiert wurde. Siehe auch : Wie kann ich eine gute Antwort schreiben .
Tân

Sieht für mich klar genug aus
Giorgio Tempesta

4

Obwohl einige Benutzer diese Frage bereits beantwortet haben, gebe ich ein Beispiel für Anwendungseinstellungen, um dieses Problem zu lösen.

Ich hatte das gleiche Problem. Ich verwende das Modul https://github.com/grevory/angular-local-storage in meiner AngularJS-Anwendung. Wenn Sie Ihre App wie folgt konfigurieren, werden Variablen im Sitzungsspeicher anstelle des lokalen Speichers gespeichert. Wenn Sie den Browser oder die Registerkarte schließen, wird der Sitzungsspeicher daher automatisch entfernt. Sie müssen nichts tun.

app.config(function (localStorageServiceProvider) {
  localStorageServiceProvider
  .setPrefix('myApp')
  .setStorageType('sessionStorage')
});

Hoffe es wird helfen.


4

Es stehen fünf Methoden zur Auswahl:

  • setItem (): Fügen Sie localStorage Schlüssel und Wert hinzu
  • getItem (): Ruft einen Wert mit dem Schlüssel von localStorage ab
  • removeItem (): Entfernen Sie ein Element per Schlüssel aus localStorage
  • clear (): Löscht alle localStorage
  • key (): Es wurde eine Nummer übergeben, um den n-ten Schlüssel eines localStorage abzurufen

Sie können clear () verwenden. Diese Methode löscht beim Aufrufen den gesamten Speicher aller Datensätze für diese Domäne. Es werden keine Parameter empfangen.

window.localStorage.clear();

3

Hier ist ein einfacher Test, um festzustellen, ob Sie Browserunterstützung haben, wenn Sie mit lokalem Speicher arbeiten:

if(typeof(Storage)!=="undefined") {
  console.log("localStorage and sessionStorage support!");
  console.log("About to save:");
  console.log(localStorage);
  localStorage["somekey"] = 'hello';
  console.log("Key saved:");
  console.log(localStorage);
  localStorage.removeItem("somekey");  //<--- key deleted here
  console.log("key deleted:");
  console.log(localStorage);
  console.log("DONE ===");
} else {
  console.log("Sorry! No web storage support..");
}

Es hat bei mir wie erwartet funktioniert (ich verwende Google Chrome). Angepasst von: http://www.w3schools.com/html/html5_webstorage.asp .


3

Ich denke nicht, dass die hier vorgestellte Lösung zu 100% korrekt ist, da das Ereignis window.onbeforeunload nicht nur aufgerufen wird, wenn der Browser / Tab geschlossen ist (was erforderlich ist), sondern auch bei allen anderen verschiedenen Ereignissen. (WAS NICHT ERFORDERLICH SEIN KANN)

Unter diesem Link finden Sie weitere Informationen zur Liste der Ereignisse, die window.onbeforeunload auslösen können: -

http://msdn.microsoft.com/en-us/library/ms536907(VS.85).aspx


Sie haben vielleicht Recht, aber was Sie gepostet haben, ist immer noch ein Kommentar, keine Antwort.
nnnnnn


3

Nachdem ich mir diese Frage 6 Jahre nach ihrer Beantwortung angesehen hatte, stellte ich fest, dass es immer noch keine ausreichende Antwort auf diese Frage gibt. was alles erreichen sollte:

  • Löschen Sie den lokalen Speicher, nachdem Sie den Browser (oder alle Registerkarten der Domäne) geschlossen haben.
  • Beibehalten des lokalen Speichers über Registerkarten hinweg, wenn mindestens eine Registerkarte aktiv bleibt
  • Behalten Sie den lokalen Speicher bei, wenn Sie eine einzelne Registerkarte neu laden

Führen Sie dieses Javascript zu Beginn jedes Seitenladens aus, um Folgendes zu erreichen:

((nm,tm) => {
    const
            l = localStorage,
            s = sessionStorage,
            tabid = s.getItem(tm) || (newid => s.setItem(tm, newid) || newid)((Math.random() * 1e8).toFixed()),
            update = set => {
                let cur = JSON.parse(l.getItem(nm) || '{}');
                if (set && typeof cur[tabid] == 'undefined' && !Object.values(cur).reduce((a, b) => a + b, 0)) {
                    l.clear();
                    cur = {};
                }
                cur[tabid] = set;
                l.setItem(nm, JSON.stringify(cur));
            };
    update(1);
    window.onbeforeunload = () => update(0);
})('tabs','tabid');

Bearbeiten: Die Grundidee hier ist die folgende:

  1. Wenn Sie von vorne beginnen, wird dem Sitzungsspeicher eine zufällige ID in einem Schlüssel namens zugewiesen tabid
  2. Der lokale Speicher wird dann mit einem Schlüssel festgelegt, tabsder ein Objekt enthält, dessen Schlüssel tabidauf 1 gesetzt ist.
  3. Wenn die Registerkarte entladen wird, werden die lokalen Speicher tabsauf ein Objekt aktualisiert, das tabidauf 0 gesetzt ist.
  4. Wenn die Registerkarte neu geladen wird, wird sie zuerst entladen und fortgesetzt. Da der Schlüssel des Sitzungsspeichers tabidvorhanden ist, wird auch der lokale Speicherschlüssel tabsmit einem Unterschlüssel des tabidlokalen Speichers nicht gelöscht.
  5. Wenn der Browser entladen wird, wird der gesamte Sitzungsspeicher gelöscht. Bei Wiederaufnahme ist der Sitzungsspeicher tabidnicht mehr vorhanden und es wird ein neuer tabidgeneriert. Da der lokale Speicher weder einen Unterschlüssel tabidnoch einen anderen hat tabid(alle Sitzungen wurden geschlossen), wird er gelöscht.
  6. Auf einer neu erstellten Registerkarte wird eine neue tabidim Sitzungsspeicher generiert. Da jedoch mindestens ein tabs[ tabid] vorhanden ist, wird der lokale Speicher nicht gelöscht

1
Wenn der Browser jedoch abstürzt, window.onbeforeunloadwird der nicht aufgerufen und tabs[tabid]der lokale Speicher wird nicht auf 0 gesetzt => Der lokale Speicher wird nie mehr gelöscht. Ich denke, ein Watchdog wäre in diesem Fall besser geeignet. Anstatt beim Laden der Registerkarte 1 zu schreiben, sollten Sie den aktuellen Zeitstempel schreiben. Dann sollten Sie im reduzierten Teil die Verzögerung aktivieren, da dieser Zeitstempel nicht zu groß ist, oder durch 0 ersetzen, wenn dies der Fall ist. Auf diese Weise sind Sie nicht auf den tatsächlichen Anruf von angewiesen onbeforeunload. Die Registerkarte muss nur von Zeit zu Zeit den Watchdog zurücksetzen , um die lokale Speicherexistenz aufrechtzuerhalten.
Xryl669

1

Dies ist eine alte Frage, aber es scheint, dass keine der obigen Antworten perfekt ist.

Wenn Sie die Authentifizierung oder vertrauliche Informationen speichern möchten, die nur beim Schließen des Browsers zerstört werden, können Sie sich auf sessionStorageund verlassenlocalStorage für Quer Registerkarte Message Passing.

Grundsätzlich lautet die Idee:

  1. Sie booten von keiner zuvor geöffneten Registerkarte, daher sind sowohl Ihre localStorageals sessionStorageauch leer (wenn nicht, können Sie die löschen localStorage). Sie müssen einen Listener für Nachrichtenereignisse auf dem registrierenlocalStorage .
  2. Der Benutzer authentifiziert / erstellt vertrauliche Informationen auf dieser Registerkarte (oder einer anderen in Ihrer Domain geöffneten Registerkarte).
  3. Sie aktualisieren das sessionStorage, um die vertraulichen Informationen zu speichern, und verwenden das localStorage, um diese Informationen zu speichern, und löschen sie dann (das Timing ist Ihnen hier egal, da das Ereignis in die Warteschlange gestellt wurde, als sich die Daten änderten). Alle anderen zu diesem Zeitpunkt geöffneten Registerkarten werden beim Nachrichtenereignis zurückgerufen und aktualisiertsessionStorage mit den vertraulichen Informationen .
  4. Wenn der Benutzer einen neuen Tab in Ihrer Domain öffnet, sessionStorageist dieser leer. Der Code muss einen Schlüssel in der localStorage(zum Beispiel :) setzen req. Jede (alle) anderen Registerkarte wird im Nachrichtenereignis zurückgerufen, siehe diesen Schlüssel, und kann mit den vertraulichen Informationen von ihrem sessionStorage(wie in 3) antworten , wenn sie solche haben.

Bitte beachten Sie, dass dieses Schema nicht von einem window.onbeforeunloadfragilen Ereignis abhängt (da der Browser geschlossen / abgestürzt werden kann, ohne dass diese Ereignisse ausgelöst werden). Außerdem ist die Zeit, in der die vertraulichen Informationen auf dem gespeichert werden, localStoragesehr gering (da Sie sich auf die Erkennung von Transientenänderungen für Kreuztabellen-Nachrichtenereignisse verlassen), sodass es unwahrscheinlich ist, dass solche vertraulichen Informationen auf der Festplatte des Benutzers verloren gehen.

Hier ist eine Demo dieses Konzepts: http://jsfiddle.net/oypdwxz7/2/


Vielen Dank für die Bearbeitung xryl669, Sie haben einen guten Punkt gemacht. Wenn ich jetzt darüber nachdenke, wäre es vielleicht am besten, einen gemeinsam genutzten Web-Worker zu verwenden? developer.mozilla.org/en-US/docs/Web/API/SharedWorker für den Fall, dass die aktuelle Browserunterstützung kein Problem darstellt
Hacktisch

Ja, Sie können entweder einen SharedWorker oder einen BroadcastChannel (oder einen lokalen Speicher wie diesen) verwenden, obwohl die ersten beiden in Edge nicht verfügbar sind. Grundsätzlich würde jede Methode funktionieren, die Kreuztabellen und Fenster kreuzt. Die Schwierigkeit besteht darin, eine zu finden, die überall mit minimalem Aufwand funktioniert.
Xryl669

1

Es gibt keine Möglichkeit, das Schließen des Browsers zu erkennen, sodass Sie localStorage wahrscheinlich nicht beim Schließen des Browsers löschen können. Es gibt jedoch eine andere Möglichkeit, die Dinge zu behandeln, die Sie mit sessionCookies verwenden können, da diese nach dem Schließen des Browsers zerstört werden. Dies habe ich in meinem Projekt implementiert.


1

Sie können einfach sessionStorage verwenden. Da sessionStorage das Löschen aller Schlüsselwerte ermöglicht, wenn das Browserfenster geschlossen wird.

Siehe dort: SessionStorage-MDN


-5

Sie können den folgenden Code verwenden, um den lokalen Speicher zu löschen:

delete localStorage.myPageDataArr;

29
Dies ist nicht der richtige Weg, um einen localStorage-Schlüssel zu löschen. Sie sollten verwenden localStorage.removeItem(key);, um einen Schlüssel zu löschen.
MT.

1
Sollte localStorage.removeItem (Schlüssel) verwenden; nicht das Schlüsselwort delete.
Rob Evans

@ MT. Warum nicht benutzen delete? Ich habe es versucht und es funktioniert. Gibt es irgendwelche Nebenwirkungen oder etwas, das wir nicht zum Löschen verwenden sollten? Vielen Dank.
user1995781

2
@ user1995781 mit deleteist nicht die beste Praxis inlocalStorage
justmyfreak

1
@justmyfreak Das ist eine Nicht-Antwort
Alvitawa
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.