Як видалити пункт 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
Якщо ви хочете очистити місцевий сховище після закриття браузера, я б поставив під сумнів ваші причини його використання.
Данхамзз

16
Ви можете мати як локальні, так і об’єкти зберігання сеансів - я б використовував sessionStorage для значень сеансу. Btw, встановивши значення undefined, не видаляє його і не видаляє його з localStorage, він просто встановлює його значення на невизначене.
kennebec

2
@kennebec - налаштування на те, undefinedщоб замінити раніше збережений елемент. Але так, використання .removeItem()більш доцільне.
nnnnnn

2
просто використовуйте sessionStorage замість localStorage
Альберто Акунья

2
Використовуйте, localStorage.clear(); якщо ви хочете очистити весь сховище.
Чорна мамба

Відповіді:


802

слід робити так, а не з оператором delete:

localStorage.removeItem(key);

1
Чому ми не можемо точно використовувати оператор видалення? З моїх тестів, здається, delete localStorage.keyпрацює так само добре localStorage.removeItem(key). Мені здається більш зрозумілим використання видалення, коли я встановлюю свої змінні як, localStorage.key = 1а не localStorage.setItem('key', 1).
Авст

6
Якщо він працює, ви можете технічно ним користуватися. Але враховуючи, що RemoveItem надається як функція-член, здається, логічно використовувати його, а не стикатися з потенційно невизначеною поведінкою за допомогою окремого оператора.
kungphu

@kungphu майте на увазі, що завжди можна (випадково) зробити localStorage.removeItem = null;, створивши localStorage.removeItem(key);потенційно погану ідею.
skeggse

31
Я не бачу, як це планувати розумні випадки. Те, що мова дозволяє людям робити руйнівні речі, не означає, що ви повинні використовувати нестандартні способи використання бібліотек як захист від неправомірного використання мови. Якщо ви або ваші колеги-розробники не розумієте різниці між викликом і призначенням, у вас є набагато більші проблеми, ніж як найкраще видалити елементи з localStorage.
кунгфу

3
@skeggse це саме тому, що це погана ідея писати localStorage.key = 1в першу чергу - щоб уникнути подібних аварій
Jivan

114

Використовувати з windowглобальним ключовим словом: -

 window.localStorage.removeItem('keyName');

6
чому використовувати вікно Object? просто localStorage.removeItem(key)прекрасно працює.
Pardeep Jain

3
перевірити це посилання stackoverflow.com/questions/5319878 / ...
Vineet

Чи справді це рішення працює для IE 11? Будь ласка, підкажіть. У мене виникають проблеми в кодовому коді 5.
Каран

95

Ви можете скористатися beforeunload подію в JavaScript.

Використовуючи ванільний JavaScript, ви можете зробити щось на кшталт:

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

Це видалить ключ до закриття вікна / вкладки браузера і запропонує підтвердити дію закриття вікна / вкладки. Я сподіваюся, що це вирішить вашу проблему.

ПРИМІТКА. onbeforeunloadМетод повинен повернути рядок.


Це було справді корисно. Можливо, було б добре прийняти відповідь (навіть після закінчення цього часу).
Річард Морган

8
@dhsto VanillaJS - це звичайний JavaScript :) Подивіться тут: Що таке VanillaJS? .
Бхарат Хатрі

1
Одна з проблем полягає в тому, що це називається, навіть якщо ви переходите на одну і ту ж сторінку, а не лише тоді, коли вкладка закрита, що може бути не тим, що призначено. Побічна примітка: повернення невизначеного з onbeforeunload призведе до відключення повідомлення, яке відображається під час вивантаження.
Стен Бонді

Що трапиться, якщо користувач хоче залишитися на сторінці, а ви вже видалили локальну пам’ять? Також рішення не працює на Chrome і IE11
oracleruiz

Чому б тоді не використовувати sessionStorage?
Сахін Прасад

94

Натомість слід використовувати sessionStorage, якщо ви хочете видалити ключ, коли браузер закриється.


3
Це найкраща відповідь; sessionStorageє засобом для того, що описує запитувач.
Бенні

8
+1 для згадки sessionStorage, але проект редактора W3C говорить: "Тривалість контексту перегляду може бути не пов'язана з терміном експлуатації самого фактичного процесу агента користувача, оскільки агент користувача може підтримувати відновлення сесій після перезавантаження".
Тамас

28
Проблема "sessionStorage" полягає в тому, що він не зберігається під час відкриття нової вкладки, наприклад, натиснувши посилання ctrl. Мені потрібен локальнийStorage / sessionStorage гібридний лол.
Едвін Стотелер

3
@EdwinStoteler мене теж. Я якось плутаю те, про що думали, коли створили це так. Мені дійсно потрібен доступ по суті до пам’яті браузера лише в пам'яті, що знищується, коли браузер закривається. Я хочу зберігати конфіденційну інформацію таким чином, щоб отримати доступ до неї у всьому домені, але я не хочу, щоб ця інформація потрапляла на будь-які жорсткі диски.
BT

19

Спробуйте використовувати

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

Сподіваюся, це працює для вас


2
Ви хочете очистити повну локальну сховище? якщо так просто використовуйтеlocalStorage.clear();
Рафаель Маркес

було зрозуміло, про що я хочу в питанні - тільки видалити + значення +
Йосеф

12
Це очистить весь місцевий склад. погане рішення!
Еммі

12

Є дуже специфічний випадок використання, коли будь-яка пропозиція використовувати sessionStorage замість localStorage насправді не допомагає. У випадку використання буде щось таке ж просто, як щось зберігається, коли у вас відкрита принаймні одна вкладка, але її недійсною, якщо закрити останню вкладку, що залишилася. Якщо вам потрібно зберегти ваші значення перехресні вкладки та вікна, sessionStorage не допоможе вам, якщо ви не ускладните своє життя слухачам, як я намагався. Тим часом localStorage було б ідеально підходить для цього, але це робить роботу надто добре, оскільки ваші дані будуть там чекати навіть після перезавантаження браузера. Я в кінцевому рахунку використовував користувацький код та логіку, яка використовує переваги обох.

Я краще поясню, а потім даю код. Спочатку зберігайте те, що вам потрібно в localStorage, потім також у localStorage створіть лічильник, який буде містити кількість відкритих вами вкладок. Це збільшуватиметься щоразу, коли сторінка завантажується, і зменшується щоразу, коли сторінка завантажується. Ви можете обрати тут події для використання, я б запропонував "завантажити" та "вивантажити". Під час завантаження потрібно виконувати завдання очищення, які ви хотіли б виконати, коли лічильник досягне 0, тобто ви закриваєте останню вкладку. Ось ця хитра частина: я не знайшов надійного і загального способу визначити різницю між перезавантаженням сторінки або навігацією всередині сторінки та закриттям вкладки. Тож якщо збережені вами дані - це не те, що ви можете відновити при завантаженні, перевіривши, що це ваша перша вкладка, тоді ви не зможете видалити його під час кожного оновлення. Натомість вам потрібно зберігати прапор у sessionStorage при кожному завантаженні, перш ніж збільшувати лічильник вкладок. Перш ніж зберігати це значення, ви можете здійснити перевірку, щоб перевірити, чи воно вже має значення, а якщо це не так, це означає, що ви завантажуєтесь у цей сеанс вперше, це означає, що ви можете зробити очищення при завантаженні, якщо це значення не встановлено, а лічильник дорівнює 0.


Як відповідь на питання "чому не використовували sessionStorage?" підхід, також від w3schools.com/html/html5_webstorage.asp : "window.sessionStorage - зберігає дані за один сеанс (дані втрачаються, коли вкладка закрита)". Тож відповідь якраз така. sessionStorage марний, якщо ви хочете щось стійке навіть у описаному вами шафі.
Солтун

3
Я думаю, що найкращою реалізацією для цього була б послуга browserWatcher, яка в основному запускає події, які інші компоненти можуть прослуховувати (наприклад, відкриття браузера, закриття браузера, завантаження браузера, завантаження браузера тощо) та приховання всіх цих деталей реалізації всередині нього . Кожен компонент може вирішити, з якими подіями йому потрібно впоратися, щоб виконати свою роботу. Єдиним моїм питанням буде, що станеться, якщо живлення перерветься на машину чи щось таке, то ці властивості залишатимуться в localStorage наступного разу, коли браузер відкриється, ?
pQuestions123

11

використовувати sessionStorage

Об'єкт sessionStorage дорівнює об’єкту 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
Дані видаляються на вкладці браузера закрити.
Космонафт

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, якщо ви включили якийсь контекст, щоб пояснити, як допомагає ваша відповідь, особливо на питання, на яке вже є прийнята відповідь. Див.: Як написати гарну відповідь .
Tân

Мені здається досить зрозумілим
Джорджіо Темпеста

4

Хоча деякі користувачі вже відповіли на це питання, я наводжу приклад налаштувань програми для вирішення цієї проблеми.

У мене було те саме питання. Я використовую https://github.com/grevory/angular-local-storage модуль у своїй програмі angularjs. Якщо ви налаштуєте додаток так, він зберігатиме змінну в сесійному сховищі замість локального сховища. Тому, якщо закрити браузер або закрити вкладку, зберігання сеансу буде видалено автоматично. Вам нічого не потрібно робити.

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

Сподіваюся, це допоможе.


4

Існує п'ять методів на вибір:

  • setItem (): додавання ключа та значення до localStorage
  • getItem (): Отримайте значення за допомогою ключа з localStorage
  • removeItem (): видаліть елемент за допомогою ключа з localStorage
  • clear (): Очистити всі локальні сховища
  • key (): Введено номер для отримання n-го ключа localStorage

Ви можете використовувати 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 подія викликається не тільки тоді, коли браузер / Tab закрито (ЯКІ ЗАБЕЗПЕЧЕННЯ), але і на всіх інших кількох подіях. (ЯКІ МОЖЕ НЕ ВИМАГАТИ)

Перейдіть за цим посиланням для отримання додаткової інформації про список подій, які можуть запустити window.onbeforeunload: -

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


Ви можете мати рацію, але все ж те, що ви розмістили, - це коментар, а не відповідь.
nnnnnn

3

чому б не використовували sessionStorage?

"Об'єкт sessionStorage дорівнює об'єкту localStorage, за винятком того, що він зберігає дані лише для одного сеансу. Дані видаляються, коли користувач закриває вікно браузера."

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


3

Переглянувши це запитання через 6 років після того, як його було задано, я виявив, що все ще немає достатньої відповіді на це питання; який повинен досягти всього наступного:

  • Очистити локальне зберігання після закриття веб-переглядача (або всіх вкладок домену)
  • Збережіть локальне зберігання на вкладках, якщо принаймні одна вкладка залишається активною
  • Збережіть локальне зберігання під час перезавантаження однієї вкладки

Виконайте цей фрагмент 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. Починаючи з нуля, сховищу сеансу присвоюється випадковий ідентифікатор у ключі, що називається tabid
  2. Потім встановлюється локальне сховище за допомогою ключа, який називається tabs об'єктом, для якого ключ tabidвстановлений у 1.
  3. Коли вкладка завантажується, локальні сховища tabs оновлюється до об'єкта, що містить tabid0.
  4. Якщо вкладка буде перезавантажена, її спочатку завантажують та відновлять. Оскільки ключ пам’яті сеансу tabidіснує, так і місцеве сховищеtabs ключ з підкладом tabidлокальної пам’яті не очищається.
  5. Коли браузер буде завантажений, все сховище сеансу буде очищено. Після відновлення сеансу зберігання tabidбільше не буде, і tabidбуде створено нове . Оскільки в локальному сховищі для цього немає підключенняtabid жодного , ані будь-якого іншогоtabid (всі сеанси були закриті), це очищено.
  6. На новій створеній вкладці створюється нове tabidв сховищі сеансів, але оскільки існує принаймні одна tabs[ tabid], локальне сховище не очищається

1
Якщо браузер window.onbeforeunloadвийде з ладу, виклик не буде викликаний, а локальний tabs[tabid]не буде встановлено на 0 => локальне сховище більше ніколи не буде очищено. Я думаю, що сторожовий дог буде більш доцільним у такому випадку, замість того, щоб писати 1 при завантаженні вкладки, слід написати поточну мітку часу. Потім у частині зменшення слід стверджувати про затримку, оскільки часова марка не надто велика, або замінити її на 0, якщо вона є. Таким чином, ви не залежите від фактичного виклику onbeforeunload. На вкладці потрібно час від часу скидати сторожову службу, щоб підтримувати існування локального сховища.
xryl669

1

Це давнє запитання, але, здається, жодна з наведених відповідей не є досконалою.

У разі , якщо ви хочете аутентифікації магазину або будь-якої конфіденційної інформації, які деградували тільки тоді , коли браузер закритий, ви можете розраховувати на sessionStorageіlocalStorage на передачу повідомлень з перехресними вкладками.

В основному ідея така:

  1. Ви завантажуєте завантаження з жодної попередньої вкладки, таким чином і ваші, localStorageі sessionStorageпорожні (якщо ні, ви можете очистити цю localStorage). Вам доведеться зареєструвати слухача подій повідомлення наlocalStorage .
  2. Користувач підтверджує / створює конфіденційну інформацію на цій вкладці (або будь-якій іншій вкладці, відкритій у вашому домені).
  3. Ви оновлюєте файл, sessionStorageщоб зберігати конфіденційну інформацію, і використовуєте localStorageдля зберігання цієї інформації, а потім видаляєте її (вас не хвилює терміни тут, оскільки подія була в черзі при зміні даних). Будь-яка інша вкладка, відкрита в цей час, буде передзвонена в події повідомлення та оновить їхsessionStorage із конфіденційною інформацією.
  4. Якщо користувач відкриє нову вкладку у вашому домені, вона sessionStorageбуде порожньою. Код повинен встановити ключ у localStorage(for example:) req. Будь-яка (усі) інша вкладка буде передзвонена в події повідомлення, перегляньте цей ключ і зможете відповісти на конфіденційну інформацію з їхньої sessionStorage(наприклад, у 3), якщо вона є.

Зауважте, що ця схема не залежить від window.onbeforeunloadкрихкої події (оскільки браузер може бути закритий / розбитий без цих подій). Крім того, часу на зберіганні чутливої ​​інформації localStorageдуже мало (оскільки ви покладаєтесь на виявлення змін трансиєнтів для події повідомлення з перехресними вкладками), тому навряд чи така конфіденційна інформація просочиться на жорсткому диску користувача.

Ось демонстрація цієї концепції: http://jsfiddle.net/oypdwxz7/2/


Дякую за редагування xryl669, ви добре зробили свою думку. Коли я зараз замислююся над цим, чи було б найкраще використовувати спільного веб-працівника? developer.mozilla.org/en-US/docs/Web/API/SharedWorker у випадку, якщо поточна підтримка браузера не є проблемою
Hacktisch

Так, ви можете використовувати або SharedWorker або BroadcastChannel (або подібний локальнийStorage), хоча перші два недоступні в Edge. В основному, будь-який метод, що має вкладку, перехресне вікно, працював би. Складність у пошуку тієї, яка працює всюди з мінімумом клопоту.
xryl669

1

Немає такого способу виявити закриття браузера, тому, ймовірно, ви не можете видалити localStorage у закритому браузері, але є інший спосіб обробляти речі, якими ви можете скористатися sessionCookies, оскільки він зруйнується після закриття браузера. Це я реалізований у своєму проекті.


0

Ви можете просто використовувати sessionStorage. Оскільки sessionStorage дозволяють очистити все значення ключа, коли вікно браузера буде закрито.

Дивіться там: SessionStorage- MDN


-5

ви можете спробувати наступний код, щоб видалити локальну пам’ять:

delete localStorage.myPageDataArr;

29
Це не правильний спосіб видалення ключа localStorage. Ви повинні використовувати localStorage.removeItem(key);для видалення ключа.
MT.

1
Потрібно використовувати localStorage.removeItem (ключ); не ключове слово видалення.
Роб Еванс

@MT. Чому б не використовувати delete? Я спробував, і це працює. Чи є якісь побічні ефекти чи щось таке, що ми не повинні використовувати delete? Дякую.
user1995781

2
@ user1995781 використання deleteне найкраща практика вlocalStorage
justmyfreak

1
@justmyfreak Це не відповідь
alvitawa
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.