Bagaimana cara menghapus item penyimpanan lokal ketika jendela / tab browser ditutup?

403

Kasus Saya: penyimpanan lokal dengan kunci + nilai yang harus dihapus ketika browser ditutup dan bukan tab tunggal.

Silakan lihat kode saya jika layak dan apa yang dapat ditingkatkan:

//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;
});
Yosef
sumber
32
Jika Anda ingin menghapus penyimpanan lokal saat browser ditutup, saya akan mempertanyakan alasan Anda menggunakannya.
Dunhamzzz
16
Anda dapat memiliki objek penyimpanan lokal dan sesi - Saya akan menggunakan sessionStorage untuk nilai sesi. Btw, mengatur nilai ke undefined tidak menghapusnya, atau menghapusnya dari localStorage, itu hanya mengatur nilainya menjadi undefined.
kennebec
2
@kennebec - Pengaturan untuk undefinedmenimpa item yang disimpan sebelumnya. Tapi ya, menggunakan .removeItem()lebih tepat.
nnnnnn
2
cukup gunakan sessionStorage alih-alih localStorage
Alberto Acuña
2
Gunakan localStorage.clear(); jika Anda ingin menghapus seluruh penyimpanan.
Black Mamba

Jawaban:

802

harus dilakukan seperti itu dan tidak dengan operator hapus:

localStorage.removeItem(key);
Yosef
sumber
1
Mengapa kita tidak bisa menggunakan operator hapus? Dari tes saya, tampaknya delete localStorage.keyberfungsi dengan baik localStorage.removeItem(key). Tampaknya lebih jelas bagi saya untuk menggunakan delete ketika saya mengatur variabel saya localStorage.key = 1suka daripada localStorage.setItem('key', 1).
Aust
6
Jika berhasil, Anda dapat menggunakannya secara teknis. Tetapi mengingat removeItem disediakan sebagai fungsi anggota, tampaknya logis untuk menggunakannya daripada menjalankan perilaku yang berpotensi tidak terdefinisi menggunakan operator terpisah.
kungphu
@ Kungphu perlu diingat bahwa seseorang selalu dapat (tidak sengaja) melakukannya localStorage.removeItem = null;, membuat localStorage.removeItem(key);ide yang berpotensi buruk.
skeggse
31
Saya tidak melihat bagaimana itu merupakan kemungkinan yang masuk akal untuk direncanakan. Fakta bahwa suatu bahasa memungkinkan orang untuk melakukan hal-hal yang merusak tidak berarti Anda harus mengadopsi cara-cara non-standar menggunakan perpustakaan sebagai pertahanan terhadap penyalahgunaan bahasa. Jika Anda atau rekan pengembang Anda tidak memahami perbedaan antara pemanggilan dan penugasan, Anda memiliki masalah yang jauh lebih besar daripada cara terbaik untuk menghapus item dari localStorage.
kungphu
3
@skeggse, inilah alasan utama menulis localStorage.key = 1di tempat pertama - untuk menghindari kecelakaan seperti ini
Jivan
114

Gunakan dengan windowkata kunci global: -

 window.localStorage.removeItem('keyName');
anggur
sumber
6
mengapa menggunakan Object window? hanya localStorage.removeItem(key)bekerja dengan baik.
Pardeep Jain
3
lihat tautan ini stackoverflow.com/questions/5319878/…
vineet
Apakah solusi ini benar-benar berfungsi untuk IE 11? Tolong sarankan. Saya mengalami masalah ini dalam kode sudut 5.
Karan
95

Anda dapat memanfaatkan beforeunloadacara dalam JavaScript.

Dengan menggunakan vanilla JavaScript Anda dapat melakukan sesuatu seperti:

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

Itu akan menghapus kunci sebelum jendela / tab browser ditutup dan meminta Anda untuk mengkonfirmasi tindakan tutup jendela / tab. Saya harap itu menyelesaikan masalah Anda.

CATATAN: onbeforeunloadMetode ini harus mengembalikan string.

MT.
sumber
Ini memang bermanfaat. Mungkin menyenangkan menerima jawabannya (bahkan setelah sekian lama).
Richard Morgan
8
@dhsto VanillaJS adalah JavaScript biasa :) Lihat di sini: Apa itu VanillaJS? .
Bharat Khatri
1
Satu masalah adalah bahwa ini disebut bahkan jika Anda menavigasi pada halaman yang sama, bukan hanya ketika tab ditutup, yang mungkin bukan yang dimaksudkan. Catatan samping: mengembalikan undefined dari onbeforeunload akan menonaktifkan pesan yang ditampilkan saat membongkar.
Stan Bondi
Apa yang terjadi jika pengguna ingin tetap di halaman dan Anda sudah menghapus penyimpanan lokal? Juga solusinya tidak bekerja pada Chrome dan
IE11
Mengapa tidak menggunakan sessionStorage?
Sachin Prasad
94

Anda harus menggunakan sessionStorage sebagai gantinya jika Anda ingin kunci dihapus ketika browser ditutup.

Graou13
sumber
3
Ini jawaban terbaik; sessionStorageadalah obat untuk apa yang dijelaskan si penanya.
Benny
8
+1 untuk disebutkan sessionStorage, tetapi Draft Editor W3C mengatakan: 'Masa pakai konteks penelusuran tidak dapat dikaitkan dengan masa proses agen pengguna yang sebenarnya itu sendiri, karena agen pengguna dapat mendukung sesi melanjutkan setelah restart.'
Tamás
28
Masalah dengan 'sessionStorage' adalah tidak disimpan ketika Anda membuka tab baru, misalnya dengan ctrl klik tautan. Saya membutuhkan lol hybrid localStorage / sessionStorage.
Edwin Stoteler
3
@ EdwinStoteler Me juga. Saya agak bingung apa yang mereka pikirkan ketika mereka mendesainnya dengan cara ini. Saya benar-benar membutuhkan akses ke penyimpanan browser hanya dalam memori yang dihancurkan ketika browser ditutup. Saya ingin menyimpan informasi sensitif dengan cara yang dapat diakses di seluruh domain, tetapi saya tidak ingin info itu mengenai hard disk.
BT
19

Coba gunakan

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

Semoga ini berhasil untuk Anda

Rafael Marques
sumber
2
Anda ingin menghapus localStorage lengkap? jika demikian gunakan sajalocalStorage.clear();
Rafael Marques
itu jelas apa yang saya inginkan dalam pertanyaan - key only delete + value
Yosef
12
Ini akan membersihkan seluruh penyimpanan lokal. solusi buruk!
Emmy
12

Ada kasus penggunaan yang sangat spesifik di mana setiap saran untuk menggunakan sessionStorage bukan localStorage tidak benar-benar membantu. Kasing akan menjadi sesuatu yang sederhana seperti menyimpan sesuatu saat Anda memiliki setidaknya satu tab dibuka, tetapi membatalkannya jika Anda menutup sisa tab terakhir. Jika Anda ingin nilai-nilai Anda disimpan tab-silang dan jendela, sessionStorage tidak membantu Anda kecuali Anda menyulitkan hidup Anda dengan pendengar, seperti yang telah saya coba. Sementara itu localStorage akan menjadi sempurna untuk ini, tetapi melakukan pekerjaan 'terlalu baik', karena data Anda akan menunggu di sana bahkan setelah restart browser. Saya akhirnya menggunakan kode khusus dan logika yang memanfaatkan keduanya.

Saya lebih suka menjelaskan daripada memberikan kode. Pertama-tama simpan apa yang Anda butuhkan di localStorage, kemudian juga di localStorage buat penghitung yang akan berisi jumlah tab yang telah Anda buka. Ini akan meningkat setiap kali halaman dimuat dan berkurang setiap kali halaman dibongkar. Anda dapat memilih di sini tentang acara yang akan digunakan, saya sarankan 'muat' dan 'bongkar'. Pada saat Anda membongkar, Anda perlu melakukan tugas pembersihan yang ingin Anda lakukan ketika penghitung mencapai 0, artinya Anda menutup tab terakhir. Inilah bagian yang sulit: Saya belum menemukan cara yang dapat diandalkan dan generik untuk mengetahui perbedaan antara memuat ulang halaman atau navigasi di dalam halaman dan penutupan tab. Jadi, jika data yang Anda simpan bukan sesuatu yang dapat Anda bangun kembali setelah memeriksa bahwa ini adalah tab pertama Anda, maka Anda tidak dapat menghapusnya di setiap penyegaran. Alih-alih, Anda perlu menyimpan bendera di sessionStorage di setiap beban sebelum menambah penghitung tab. Sebelum menyimpan nilai ini, Anda dapat melakukan pengecekan untuk melihat apakah sudah memiliki nilai dan jika tidak, ini berarti Anda memuat ke dalam sesi ini untuk pertama kalinya, artinya Anda dapat melakukan pembersihan saat memuat jika ini nilai tidak diatur dan penghitung adalah 0.

Solthun
sumber
Sebagai jawaban untuk "mengapa tidak menggunakan sessionStorage?" pendekatan, juga dari w3schools.com/html/html5_webstorage.asp : "window.sessionStorage - menyimpan data untuk satu sesi (data hilang ketika tab ditutup)". Jadi jawabannya hanya itu. sessionStorage tidak berguna jika Anda menginginkan sesuatu yang gigih bahkan dalam usecase yang saya jelaskan.
Solthun
3
Saya pikir implementasi terbaik untuk ini adalah layanan browserWatcher yang pada dasarnya memecat acara yang dapat didengarkan komponen lain (yaitu buka browser, tutup browser, buka-broswer, buka browser-dll, dan sembunyikan semua detail implementasi di dalamnya Setiap komponen dapat memutuskan acara mana yang perlu ditangani untuk melakukan tugasnya. Satu-satunya pertanyaan saya adalah apa yang terjadi jika listrik terputus ke mesin atau sesuatu, maka properti ini akan tetap di lokal. Penyimpanan pada saat browser dibuka tidak akankah mereka ?
pQuestions123
11

gunakan sessionStorage

Objek sessionStorage sama dengan objek localStorage, kecuali bahwa itu menyimpan data hanya untuk satu sesi. Data dihapus ketika pengguna menutup jendela browser.

Contoh berikut menghitung berapa kali pengguna mengklik tombol, pada sesi saat ini:

Contoh

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.";
Dilan
sumber
1
Data dihapus pada tab browser tutup.
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]);
}
Gil Snovsky
sumber
5
localStorage.removeItem(key);  //item

localStorage.clear(); //all items
William Cauich
sumber
1
Saat menjawab pertanyaan lama, jawaban Anda akan jauh lebih berguna bagi pengguna StackOverflow lain jika Anda menyertakan beberapa konteks untuk menjelaskan bagaimana jawaban Anda membantu, terutama untuk pertanyaan yang sudah memiliki jawaban yang diterima. Lihat: Bagaimana saya menulis jawaban yang bagus .
Tân
Tampak cukup jelas bagi saya
Giorgio Tempesta
4

Meskipun, beberapa pengguna sudah menjawab pertanyaan ini, saya memberikan contoh pengaturan aplikasi untuk mengatasi masalah ini.

Saya memiliki masalah yang sama. Saya menggunakan modul https://github.com/grevory/angular-local-storage dalam aplikasi angularjs saya. Jika Anda mengonfigurasi aplikasi Anda sebagai berikut, itu akan menyimpan variabel dalam penyimpanan sesi, bukan penyimpanan lokal. Karena itu, jika Anda menutup browser atau menutup tab, penyimpanan sesi akan dihapus secara otomatis. Anda tidak perlu melakukan apa pun.

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

Semoga ini bisa membantu.

pengguna1012513
sumber
4

Ada lima metode untuk dipilih:

  • setItem (): Tambahkan kunci dan nilai ke localStorage
  • getItem (): Ambil nilai dengan kunci dari localStorage
  • removeItem (): Hapus item dengan kunci dari localStorage
  • clear (): Bersihkan semua penyimpanan lokal
  • key (): Melewati angka untuk mengambil kunci n dari penyimpanan lokal

Anda dapat menggunakan clear (), metode ini ketika dipanggil membersihkan seluruh penyimpanan semua catatan untuk domain itu. Itu tidak menerima parameter apa pun.

window.localStorage.clear();
marcorchito8
sumber
3

Berikut adalah tes sederhana untuk melihat apakah Anda memiliki dukungan browser ketika bekerja dengan penyimpanan lokal:

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

Itu bekerja untuk saya seperti yang diharapkan (saya menggunakan Google Chrome). Diadaptasi dari: http://www.w3schools.com/html/html5_webstorage.asp .

rdonatoiop
sumber
3

Saya tidak berpikir solusi yang disajikan di sini adalah 100% benar karena window.onbeforeunload acara dipanggil tidak hanya ketika browser / Tab ditutup (YANG DIPERLUKAN), tetapi juga pada semua beberapa acara lainnya. (YANG MUNGKIN TIDAK DIBUTUHKAN)

Lihat tautan ini untuk informasi lebih lanjut tentang daftar peristiwa yang dapat memunculkan window.onbeforeunload: -

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

miztaken
sumber
Anda mungkin benar, tetapi tetap apa yang Anda posting adalah komentar, bukan jawaban.
nnnnnn
3

mengapa tidak menggunakan sessionStorage?

"Objek sessionStorage sama dengan objek localStorage, kecuali bahwa itu menyimpan data hanya untuk satu sesi. Data dihapus ketika pengguna menutup jendela browser."

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

wjfinder77
sumber
3

Setelah melihat pertanyaan ini 6 tahun setelah ditanyakan, saya menemukan bahwa masih belum ada jawaban yang memadai untuk pertanyaan ini; yang harus mencapai semua hal berikut:

  • Bersihkan Penyimpanan Lokal setelah menutup browser (atau semua tab domain)
  • Pertahankan Penyimpanan Lokal di seluruh tab, jika setidaknya satu tab tetap aktif
  • Pertahankan Penyimpanan Lokal saat memuat ulang satu tab

Jalankan potongan javascript ini di awal setiap pemuatan halaman untuk mencapai hal di atas:

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

Sunting: Ide dasar di sini adalah sebagai berikut:

  1. Ketika mulai dari awal, penyimpanan sesi diberikan id acak di tombol yang disebut tabid
  2. Penyimpanan lokal kemudian diatur dengan kunci yang disebut tabsberisi objek kunci tabidtersebut diatur ke 1.
  3. Ketika tab diturunkan, penyimpanan lokal tabsdiperbarui ke objek yang berisi tabidset ke 0.
  4. Jika tab dimuat ulang, itu pertama diturunkan, dan dilanjutkan. Karena kunci penyimpanan sesi tabidada, dan begitu juga tabskunci penyimpanan lokal dengan sub-kunci tabidpenyimpanan lokal tidak dihapus.
  5. Ketika browser diturunkan, semua penyimpanan sesi akan dihapus. Saat melanjutkan, penyimpanan sesi tabidtidak akan ada lagi dan yang baru tabidakan dihasilkan. Karena penyimpanan lokal tidak memiliki sub-kunci untuk ini tabid, atau yang lainnya tabid(semua sesi ditutup), maka dihapus.
  6. Setelah tab baru dibuat, baru tabiddihasilkan di penyimpanan sesi, tetapi karena setidaknya satu tabs[ tabid] ada, penyimpanan lokal tidak dihapus
Hacktisch
sumber
1
Namun, jika browser mogok, window.onbeforeunloadmaka tidak akan dipanggil, dan lokal tabs[tabid]tidak akan disetel ke 0 => penyimpanan lokal tidak akan pernah dihapus lagi. Saya pikir pengawas akan lebih tepat dalam hal itu, daripada menulis 1 pada pemuatan tab, Anda harus menulis cap waktu saat ini. Kemudian di bagian pengurangan, Anda harus menyatakan penundaan karena cap waktu itu tidak terlalu besar atau ganti dengan 0 jika itu. Dengan begitu, Anda tidak bergantung pada panggilan sebenarnya onbeforeunload. Tab hanya perlu mengatur ulang pengawas dari waktu ke waktu untuk mempertahankan keberadaan penyimpanan lokal.
xryl669
1

Ini adalah pertanyaan lama, tetapi sepertinya tidak ada jawaban di atas yang sempurna.

Jika Anda ingin menyimpan otentikasi atau informasi sensitif apa pun yang dihancurkan hanya ketika browser ditutup, Anda dapat mengandalkan sessionStoragedan localStorageuntuk meneruskan pesan antar tab.

Pada dasarnya, idenya adalah:

  1. Anda bootstrap dari tidak ada tab sebelumnya yang dibuka, sehingga Anda localStoragedan sessionStoragekosong (jika tidak, Anda dapat menghapus localStorage). Anda harus mendaftarkan pendengar acara pesan di localStorage.
  2. Pengguna mengautentikasi / membuat info sensitif pada tab ini (atau tab lain yang dibuka di domain Anda).
  3. Anda memperbarui sessionStorageuntuk menyimpan informasi sensitif, dan menggunakan localStorageuntuk menyimpan informasi ini, lalu menghapusnya (Anda tidak peduli tentang waktu di sini, karena acara itu antri ketika data berubah). Tab lain yang dibuka pada saat itu akan dipanggil kembali pada acara pesan, dan akan memperbarui mereka sessionStoragedengan informasi sensitif.
  4. Jika pengguna membuka tab baru di domain Anda, itu sessionStorageakan kosong. Kode harus menetapkan kunci di localStorage(untuk contoh:) req. Tab lainnya (semua) akan dipanggil kembali di acara pesan, lihat kunci itu, dan dapat menjawab dengan informasi sensitif dari sessionStorage(seperti pada 3), jika ada.

Harap perhatikan bahwa skema ini tidak bergantung pada window.onbeforeunloadacara yang rapuh (karena browser dapat ditutup / macet tanpa acara ini dipecat). Selain itu, waktu informasi sensitif disimpan pada localStoragesangat kecil (karena Anda mengandalkan deteksi perubahan transcien untuk acara pesan tab silang) sehingga tidak mungkin bahwa informasi sensitif tersebut bocor pada hard drive pengguna.

Berikut ini demo konsep ini: http://jsfiddle.net/oypdwxz7/2/

xryl669
sumber
Terima kasih atas hasil edit xryl669, Anda membuat poin yang bagus. Ketika saya sekarang memikirkan hal ini, apakah mungkin lebih baik menggunakan pekerja web bersama? developer.mozilla.org/en-US/docs/Web/API/SharedWorker seandainya dukungan browser saat ini tidak menjadi masalah
Hacktisch
Ya, Anda bisa menggunakan SharedWorker atau BroadcastChannel (atau Penyimpanan lokal seperti ini), meskipun dua yang pertama tidak tersedia di Edge. Pada dasarnya, metode apa pun yang tab lintas, lintas jendela, akan bekerja. Kesulitannya adalah menemukan yang bekerja di mana-mana dengan minimal kerumitan.
xryl669
1

Tidak ada cara seperti itu untuk mendeteksi penutupan browser jadi mungkin Anda tidak dapat menghapus penyimpanan lokal pada penutupan browser tetapi ada cara lain untuk menangani hal-hal yang Anda dapat menggunakan sessionCookies karena akan hancur setelah browser tutup. Ini saya terapkan dalam proyek saya.

Amit Dwivedi
sumber
1

Anda cukup menggunakan sessionStorage. Karena sessionStorage memungkinkan untuk menghapus semua nilai kunci ketika jendela browser akan ditutup.

Lihat di sana: SessionStorage- MDN

Moshiur Rahman
sumber
-5

Anda dapat mencoba kode berikut untuk menghapus penyimpanan lokal:

delete localStorage.myPageDataArr;
aztechy
sumber
29
Ini bukan cara yang tepat untuk menghapus kunci Penyimpanan lokal. Anda harus menggunakan localStorage.removeItem(key);untuk menghapus kunci.
MT.
1
Harus menggunakan localStorage.removeItem (kunci); bukan kata kunci hapus.
Rob Evans
@ MT. Kenapa tidak menggunakan delete? Saya mencoba, dan itu berhasil. Apakah ada efek samping atau sesuatu yang tidak boleh kita gunakan hapus? Terima kasih.
user1995781
2
@ user1995781 menggunakan deletebukan praktik terbaik dalamlocalStorage
justmyfreak
1
@justmyfreak Itu bukan jawaban
alvitawa