ブラウザウィンドウ/タブが閉じているときにlocalStorageアイテムを削除するにはどうすればよいですか?


403

私のケース:キーと値を含むlocalStorageは、ブラウザーが閉じられたときに削除され、単一のタブではありません。

それが適切で何が改善できるかは私のコードを見てください:

//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
ブラウザを閉じたときにローカルストレージをクリアしたい場合は、それを使用する理由について質問します。
Dunhamzzz

16
ローカルとセッションの両方のストレージオブジェクトを使用できます。セッションの値にはsessionStorageを使用します。ところで、値をundefinedに設定しても、値は削除されず、localStorageからも削除されません。値がundefinedに設定されるだけです。
ケネベック2012年

2
@kennebec-に設定するundefinedと、以前に保存されたアイテムが上書きされます。しかし、はい、使用する.removeItem()方が適切です。
nnnnnn 2013年

2
だけではなく、のlocalStorageの使用のsessionStorage
アルベルト・アクーニャ

2
localStorage.clear(); ストレージ全体を消去する場合に使用します。
ブラックマンバ2017

回答:


802

削除演算子ではなくそのように実行する必要があります:

localStorage.removeItem(key);

1
正確に削除演算子を使用できないのはなぜですか?私のテストから、それはとdelete localStorage.key同じようにうまく機能するようlocalStorage.removeItem(key)です。変数をlocalStorage.key = 1ではなくのように設定する場合は、deleteを使用する方が明確に思えますlocalStorage.setItem('key', 1)
オースト

6
動作する場合、技術的に使用できます。しかし、removeItemがメンバー関数として提供されていることを考えると、別の演算子を使用して未定義の可能性のある動作に遭遇するのではなく、それを使用するのが理にかなっています。
kungphu 2016

@kungphuは常に(誤って)行うことができます心の1に維持localStorage.removeItem = null;すること、localStorage.removeItem(key);潜在的に貧しい人々のアイデアを。
skeggse 2016

31
それがどのように計画するのに合理的な偶然であるかはわかりません。言語が破壊的なことを可能にするという事実は、言語の誤用に対する防御策としてライブラリを使用する非標準的な方法を採用する必要があることを意味しません。あなたまたはあなたの仲間の開発者が呼び出しと割り当ての違いを理解していない場合、localStorageからアイテムを削除する最善の方法よりもはるかに大きな問題があります。
kungphu 2016

3
それは、書き込みに悪い考えだ理由を正確この@skeggseあるlocalStorage.key = 1事故のこの種のを避けるために-最初の場所で
Jivan

114

windowグローバルキーワードで使用:-

 window.localStorage.removeItem('keyName');

6
ウィンドウオブジェクトを使用する理由 単にlocalStorage.removeItem(key)うまくいきます。
Pardeep Jain 2016

3
このリンクを確認してください。stackoverflow.com
questions/5319878/…

このソリューションは本当にIE 11で機能しますか?提案してください。私は角度5コードでこの問題を抱えています。
Karan

95

beforeunloadJavaScriptでイベントを利用できます。

バニラJavaScriptを使用すると、次のようなことができます。

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

これにより、ブラウザウィンドウ/タブが閉じる前にキーが削除され、ウィンドウ/タブを閉じるアクションを確認するように求められます。これで問題が解決することを願っています。

注:onbeforeunloadメソッドは文字列を返す必要があります。


これは確かに役に立ちました。答えを受け入れるのは良いことかもしれません(今でも結局です)。
Richard Morgan

8
@dhsto VanillaJSは単純なJavaScriptです:)ここを見てください:VanillaJSとは何ですか?
Bharat Khatri 14

1
1つの問題は、タブが閉じられたときだけでなく、同じページに移動しても呼び出されることです。補足:onbeforeunloadからundefinedを返すと、アンロード時に表示されるメッセージが無効になります。
スタンボンディ2014

ユーザーがページに留まることを望んでいて、ローカルストレージをすでに削除している場合はどうなりますか?また、このソリューションはChromeとIE11では機能しません
oracleruiz

では、なぜsessionStorageを使用しないのですか?
Sachin Prasad

94

ブラウザーを閉じたときにキーを削除する場合は、代わりにsessionStorageを使用する必要があります。


3
これが最良の答えです。sessionStorage質問者が説明する内容に対する救済策です。
Benny、

8
言及のための+1 sessionStorageが、W3Cエディタのドラフトは言う:「ユーザエージェントは、再起動後にセッションを再開サポートすることが可能とブラウジング・コンテキストの寿命は、実際のユーザー・エージェント・プロセス自体の寿命とは関係のないことができます」
タマシュ

28
'sessionStorage'の問題は、Ctrlキーを押しながらリンクをクリックするなどして、新しいタブを開いたときに保存されないことです。localStorage / sessionStorageハイブリッドlolが必要です。
Edwin Stoteler、2015年

3
@EdwinStoteler私も。彼らがこのように設計したときに彼らが何を考えていたのか、ちょっと混乱しています。ブラウザーを閉じると破棄される、メモリ内のみのブラウザーストレージに本質的にアクセスする必要があります。機密情報をドメイン全体からアクセスできる方法で保存したいのですが、その情報がハードディスクに当たらないようにしたいのです。
BT

19

使ってみてください

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

これがあなたのためにうまくいくことを願っています


2
完全なlocalStorageをクリアしますか?使用する場合localStorage.clear();
Rafael Marques

それは私が問題にしたいものは明らかでした-キーのみ削除+値
Yosef

12
これにより、ローカルストレージ全体がクリーンアップされます。悪い解決法!
エミー

12

localStorageの代わりにsessionStorageを使用するという提案が実際には役に立たないという非常に特殊な使用例があります。ユースケースは、少なくとも1つのタブを開いている間に何かを保存するのと同じくらい簡単ですが、残っている最後のタブを閉じると無効になります。値をクロス集計とウィンドウに保存する必要がある場合、私が試したようにリスナーで生活を複雑にしない限り、sessionStorageは役に立ちません。それまでの間、localStorageはこれに最適ですが、ブラウザの再起動後でもデータが待機しているため、「十分すぎるほど」機能します。最終的に、両方を利用するカスタムコードとロジックを使用することになりました。

私はむしろ説明してからコードを与えたいと思います。最初に必要なものをlocalStorageに保存し、次にlocalStorageにも開いたタブの数を含むカウンターを作成します。これは、ページが読み込まれるたびに増加し、ページがアンロードされるたびに減少します。ここで使用するイベントを選択できます。「ロード」と「アンロード」をお勧めします。アンロードするときに、カウンターが0に達したとき、つまり最後のタブを閉じているときに行うクリーンアップタスクを実行する必要があります。ここで注意が必要な部分があります。ページのリロードまたはページ内のナビゲーションとタブを閉じることの違いを確認するための信頼できる一般的な方法が見つかりませんでした。保存するデータが、これが最初のタブであることを確認した後、ロード時に再構築できるものでない場合は、更新するたびに削除することはできません。代わりに、タブカウンターを増やす前に、すべてのロードでsessionStorageにフラグを保存する必要があります。この値を格納する前に、値がすでにあるかどうかを確認できます。値がない場合は、このセッションに初めてロードすることを意味します。つまり、この場合、ロード時にクリーンアップを実行できます。値は設定されておらず、カウンタは0です。


「sessionStorageを使用しない理由」に対する回答として。アプローチ、同じくw3schools.com/html/html5_webstorage.aspから: "window.sessionStorage-1つのセッションのデータを保存します(タブが閉じられるとデータは失われます)"。だから答えはそれだけです。私が説明したユースケースでも永続的なものを必要とする場合、sessionStorageは役に立ちません。
Solthun 2015年

3
これの最良の実装は、他のコンポーネントがリッスンできるイベントを起動するbrowserWatcherサービス(つまり、ブラウザオープン、ブラウザクローズ、ブラウザロード、ブラウザアンロードなど)であり、これらのすべての実装の詳細を内部に隠すと考えています各コンポーネントは、その処理を行うために処理する必要のあるイベントを決定できます。私の唯一の質問は、マシンまたは何かに電力が供給されなくなった場合に何が起こるかということです。これらのプロパティは、次にブラウザーが開かれたときにlocalStorageにとどまります?
pQuestions123 2016年

11

sessionStorageを使用する

sessionStorageオブジェクトは、1つのセッションのデータのみを格納することを除いて、localStorageオブジェクトと同じです。ユーザーがブラウザウィンドウを閉じると、データは削除されます。

次の例では、現在のセッションでユーザーがボタンをクリックした回数をカウントします。

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
ブラウザのタブを閉じるとデータが削除されます。
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
古い質問に回答するとき、回答がどのように役立つかを説明するコンテキストを含めれば、回答は他のStackOverflowユーザーにとって非常に役立ちます。特に、既に回答が承認されている質問の場合はそうです。参照:良い回答を書くにはどうすればよいですか
2019年

私には十分にはっきり見える
ジョルジオテンペスタ

4

一部のユーザーはすでにこの質問にすでに回答していますが、この問題を解決するためのアプリケーション設定の例を示しています。

同じ問題がありました。angularjsアプリケーションでhttps://github.com/grevory/angular-local-storageモジュールを使用しています。アプリを次のように構成すると、ローカルストレージではなくセッションストレージに変数が保存されます。したがって、ブラウザを閉じるかタブを閉じると、セッションストレージは自動的に削除されます。何もする必要はありません。

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

それがお役に立てば幸いです。


4

5つの方法から選択できます。

  • setItem():キーと値をlocalStorageに追加します
  • getItem():localStorageからキーによって値を取得します
  • removeItem():localStorageからキーによって項目を削除します
  • clear():すべてのlocalStorageをクリアします
  • key():localStorageのn番目のキーを取得するために数値を渡しました

このメソッドを呼び出すと、clear()を使用して、そのドメインのすべてのレコードのストレージ全体をクリアできます。パラメータを受け取りません。

window.localStorage.clear();

3

ローカルストレージを使用するときにブラウザがサポートされているかどうかを確認する簡単なテストを次に示します。

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..");
}

期待どおりに機能しました(Google Chromeを使用しています)。複製元:http : //www.w3schools.com/html/html5_webstorage.asp


3

ここで提示されている解決策は100%正しいとは思いません。これは、window.onbeforeunloadイベントは、ブラウザー/タブが閉じられたとき(必要な場合)だけでなく、他のすべてのイベントでも呼び出されるためです。(必要ないかもしれません)

window.onbeforeunloadを起動できるイベントのリストの詳細については、このリンクを参照してください。

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


あなたは正しいかもしれませんが、それでもあなたが投稿したのはコメントではなく、答えです。
nnnnnn 2013年

3

sessionStorageを使用しないのはなぜですか?

「sessionStorageオブジェクトは、1つのセッションのデータのみを保存することを除いて、localStorageオブジェクトと同じです。データは、ユーザーがブラウザウィンドウを閉じると削除されます。」

http://www.w3schools.com/html/html5_webstorage.asp


3

質問されてから6年後にこの質問を調べたところ、この質問に対する答えはまだ十分ではないことがわかりました。これにより、次のすべてが達成されます。

  • ブラウザ(またはドメインのすべてのタブ)を閉じた後、ローカルストレージをクリアする
  • 少なくとも1つのタブがアクティブなままの場合、タブ間でローカルストレージを保持する
  • 1つのタブを再読み込みするときにローカルストレージを保持する

上記を実現するために、各ページのロードの開始時にこのJavaScriptを実行します。

((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');

編集:ここでの基本的な考え方は次のとおりです。

  1. 最初から開始すると、セッションストレージには、呼び出されたキーのランダムなIDが割り当てられます tabid
  2. 次に、ローカルストレージは、tabsキーtabidが1に設定されているオブジェクトを含むと呼ばれるキーで設定されます。
  3. タブがアンロードされると、ローカルストレージが0に設定tabsされたオブジェクトに更新tabidされます。
  4. タブが再ロードされると、最初にアンロードされて再開されます。セッションストレージのキーtabidが存在し、ローカルストレージtabsのサブキーを持つローカルストレージキーも存在するため、tabidクリアされません。
  5. ブラウザがアンロードされると、すべてのセッションストレージがクリアされます。セッションを再開すると、ストレージtabidはもう存在せず、新しいものtabidが生成されます。ローカルストレージにはthisのサブキーがないため、tabid他のtabid(すべてのセッションが閉じられていたため)、クリアされています。
  6. 新しく作成されたタブでtabidは、セッションストレージに新しいタブが生成されますが、少なくとも1つのtabs[ tabid]が存在するため、ローカルストレージは消去されません

1
ただし、ブラウザがクラッシュした場合、はwindow.onbeforeunload呼び出されず、ローカルtabs[tabid]は0に設定されません=>ローカルストレージが消去されることはありません。その場合、ウォッチドッグの方が適切だと思います。タブのロード時に1を書き込むのではなく、現在のタイムスタンプを書き込む必要があります。次に、reduce部分で、タイムスタンプが大きすぎないため遅延をアサートするか、そうであれば0に置き換えます。そうすれば、実際のの呼び出しに依存することはありませんonbeforeunload。タブは、ローカルストレージの存在を維持するために、時々ウォッチドッグをリセットする必要があるだけです。
xryl669

1

これは古い質問ですが、上記の答えのいずれも完璧ではないようです。

ブラウザーを閉じたときにのみ破棄される認証情報や機密情報を保存したい場合はsessionStoragelocalStorage、クロスタブのメッセージパッシングのため。

基本的に、アイデアは次のとおりです。

  1. 以前に開いたタブがないためブートストラップを実行しているため、localStorageとの両方sessionStorageが空です(そうでない場合は、をクリアできますlocalStorage)。にメッセージイベントリスナーを登録する必要があります。localStorage
  2. ユーザーは、このタブ(またはドメインで開いている他のタブ)で機密情報を認証/作成します。
  3. を更新しsessionStorageて機密情報を保存し、を使用しlocalStorageてこの情報を保存してから、それを削除します(データが変更されたときにイベントがキューに入れられたため、ここでタイミングを気にする必要はありません)。そのときに開かれた他のタブはすべてメッセージイベントでコールバックされsessionStorage、機密情報で更新されます。
  4. ユーザーがドメインで新しいタブを開いた場合、そのタブはsessionStorage空になります。コードは、localStorage(例:)にキーを設定する必要がありますreq。他のすべてのタブはメッセージイベントでコールバックされ、そのキーを確認し、sessionStorage(3のように)それらの機密情報があれば、それらの機密情報で応答できます。

このスキームwindow.onbeforeunloadは壊れやすいイベントに依存しないことに注意してください(これらのイベントが発生せずにブラウザーを閉じる/クラッシュできるため)。また、機密情報がに保存される時間localStorageは非常に短いので(クロス集計メッセージイベントのトランジェント変更検出に依存しているため)、ユーザーのハードドライブに機密情報が漏洩する可能性はほとんどありません。

これがこのコンセプトのデモです:http : //jsfiddle.net/oypdwxz7/2/


xryl669を編集していただき、ありがとうございます。これについて今考えているとき、共有Webワーカーを使用するのがおそらく最善でしょうか?現在のブラウザーサポートが問題ではない場合のdeveloper.mozilla.org/en-US/docs/Web/API/SharedWorker
Hacktisch

はい、SharedWorkerまたはBroadcastChannel(またはこのようなlocalStorage)のいずれかを使用できますが、最初の2つはEdgeでは使用できません。基本的に、クロスタブ、クロスウィンドウのいずれの方法でも機能します。問題は、最小限の手間でどこでも機能するものを見つけることです。
xryl669

1

ブラウザのクローズを検出する方法はないので、おそらくブラウザのクローズでlocalStorageを削除することはできませんが、ブラウザのクローズ後に破壊されるため、sessionCookiesを使用してできることを処理する別の方法があります。これは私のプロジェクトに実装されています。



-5

次のコードを試して、ローカルストレージを削除できます。

delete localStorage.myPageDataArr;

29
これは、localStorageキーを削除する正しい方法ではありません。localStorage.removeItem(key);キーを削除するには、を使用する必要があります。
MT。

1
localStorage.removeItem(key);を使用する必要があります deleteキーワードではありません。
Rob Evans

@MT。なぜ使用しないのdeleteですか?私が試したところ、うまくいきました。deleteを使用してはいけない副作用や何かがありますか?ありがとうございました。
user1995781 2014

2
@ user1995781を使用することdeleteはベストプラクティスではありませんlocalStorage
justmyfreak

1
@justmyfreakそれは答えではありません
alvitawa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.