Как удалить элемент localStorage, когда окно / вкладка браузера закрыты?

308

My Case: 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;
});
  • 25
    Если вы хотите очистить локальное хранилище после закрытия браузера, я бы поставил под сомнение ваши причины его использования.
  • 15
    Вы можете иметь как локальные, так и сессионные объекты хранения - я бы использовал sessionStorage для значений сессии. Кстати, установка значения в undefined не удаляет его и не удаляет его из localStorage, а просто устанавливает его значение в undefined.
Показать ещё 3 комментария
Теги:
local-storage

16 ответов

612
Лучший ответ

должно выполняться так, а не с оператором delete:

localStorage.removeItem(key);
  • 1
    Почему мы не можем использовать оператор удаления? Из моих тестов кажется, что delete localStorage.key работает так же хорошо, как localStorage.removeItem(key) . Мне кажется более понятным использовать delete, когда я устанавливаю свои переменные, такие как localStorage.key = 1 а не localStorage.setItem('key', 1) .
  • 5
    Если это работает, вы можете использовать его технически. Но, учитывая, что removeItem предоставляется как функция-член, кажется логичным использовать его, а не сталкиваться с потенциально неопределенным поведением, используя отдельный оператор.
Показать ещё 5 комментариев
93

Вы можете использовать событие beforeunload в JavaScript.

Используя ванильный JavaScript, вы можете сделать что-то вроде:

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

Это удалит ключ до закрытия окна браузера/вкладки и предложит подтвердить действие закрытия окна/вкладки. Я надеюсь, что решает вашу проблему.

ПРИМЕЧАНИЕ. Метод onbeforeunload должен возвращать строку.

  • 0
    Это было действительно полезно. Было бы неплохо принять ответ (даже после всего этого времени).
  • 8
    @dhsto VanillaJS - простой JavaScript :) Посмотрите здесь: Что такое VanillaJS? ,
Показать ещё 5 комментариев
83

Используйте с window глобальное ключевое слово: -

 window.localStorage.removeItem('keyName');
  • 3
    зачем использовать окно Object? просто localStorage.removeItem(key) работает нормально.
  • 3
    проверьте эту ссылку stackoverflow.com/questions/5319878/…
Показать ещё 1 комментарий
81

Вместо этого вы должны использовать sessionStorage, если хотите, чтобы ключ был удален при закрытии браузера.

  • 3
    Это лучший ответ; sessionStorage - это средство от того, что описывает sessionStorage .
  • 7
    +1 за упоминание sessionStorage , но в проекте редактора W3C говорится: «Время существования контекста просмотра может быть не связано со временем жизни самого процесса пользовательского агента, поскольку пользовательский агент может поддерживать возобновление сеансов после перезапуска».
Показать ещё 2 комментария
16

Попробуйте использовать

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

Надеюсь, это сработает для вас.

  • 0
    не работает, объект не имеет четкого метода.
  • 1
    Вы хотите очистить весь localStorage? если это так, просто используйте localStorage.clear();
Показать ещё 2 комментария
11

Существует очень конкретный вариант использования, в котором любое предложение использовать sessionStorage вместо localStorage действительно не помогает. Вариант использования был бы таким же простым, как наличие чего-то, хранящегося при открытии хотя бы одной вкладки, но недействительным, если вы закроете оставшуюся вкладку. Если вам нужны ваши значения для сохранения кросс-вкладок и окна, sessionStorage не поможет вам, если вы не усложняете свою жизнь слушателями, как я и пытался. Тем временем localStorage был бы идеален для этого, но он работает слишком хорошо, так как ваши данные будут ждать там даже после перезапуска браузера. Я закончил тем, что использовал собственный код и логику, которые используют преимущества обоих.

Я бы лучше объяснил, дайте код. Сначала сохраните то, что вам нужно, в localStorage, затем также в localStorage создайте счетчик, который будет содержать количество открываемых вкладок. Это будет увеличиваться каждый раз, когда страница загружается и уменьшается каждый раз, когда страница выгружается. Здесь вы можете выбрать, какие события использовать, я бы предложил "загрузить" и "разгрузить". В то время, когда вы выгружаетесь, вам нужно выполнить задачи очистки, которые вы хотите, когда счетчик достигнет 0, а это означает, что вы закрываете последнюю вкладку. Вот сложная часть: я не нашел надежного и общего способа рассказать разницу между перезагрузкой страницы или навигацией внутри страницы и закрытием вкладки. Поэтому Если хранящиеся данные не являются чем-то, что вы можете восстановить при загрузке после проверки, что это ваша первая вкладка, вы не можете удалить ее при каждом обновлении. Вместо этого вам нужно сохранить флаг в sessionStorage при каждой загрузке, прежде чем увеличивать счетчик табуляции. Перед сохранением этого значения вы можете сделать чек, чтобы узнать, имеет ли он уже значение, а если нет, это означает, что вы загружаетесь в этот сеанс в первый раз, что означает, что вы можете выполнить очистку при загрузке, если это значение не установлено, а счетчик равен 0.

  • 0
    Как ответ на вопрос "почему не используется sessionStorage?" подход, также с w3schools.com/html/html5_webstorage.asp : «window.sessionStorage - сохраняет данные за один сеанс (данные теряются при закрытии вкладки)». Так что ответ только на это. sessionStorage бесполезен, если вы хотите что-то постоянное даже в описанном выше случае использования.
  • 2
    Я думаю, что лучшей реализацией для этого была бы служба browserWatcher, которая в основном генерирует события, которые могут прослушивать другие компоненты (например, открывать браузер, закрывать браузер, загружать браузер, выгружать браузер и т. Д. И скрывать все эти детали реализации внутри него). Каждый компонент может решить, какие события он должен обработать, чтобы выполнить свою работу. Мой единственный вопрос будет состоять в том, что произойдет, если питание компьютера будет отключено или что-то подобное, тогда эти свойства останутся в localStorage при следующем открытии браузера, не ?
8

использовать 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
    Данные удаляются на вкладке браузера.
3
        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]);
      }
3

Хотя некоторые пользователи уже уже ответили на этот вопрос, я приводил пример настроек приложения для решения этой проблемы.

У меня была такая же проблема. Я использую https://github.com/grevory/angular-local-storage модуль в моем приложении angularjs. Если вы настроите свое приложение следующим образом, оно сохранит переменную в хранилище сеансов вместо локального хранилища. Поэтому, если вы закроете браузер или закроете вкладку, хранилище сеансов будет удалено автоматически. Вам не нужно ничего делать.

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

Надеюсь, это поможет.

3

Я не думаю, что решение, представленное здесь, на 100% правильное, потому что событие window.onbeforeunload вызывается не только при закрытии браузера /Tab (КОТОРЫЙ НЕОБХОДИМО), но также и во всех других событиях. (КОТОРЫЙ НЕ МОЖЕТ БЫТЬ НЕОБХОДИМО)

См. эту ссылку для получения дополнительной информации о списке событий, которые могут запускать window.onbeforeunload: -

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

  • 0
    Вы можете быть правы, но все же то, что вы опубликовали, это комментарий, а не ответ.
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.

2

почему не используется sessionStorage?

"Объект sessionStorage равен объекту localStorage, за исключением того, что он хранит данные только для одного сеанса. Данные удаляются, когда пользователь закрывает окно браузера."

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

1

Посмотрев на этот вопрос через 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 локального хранилища обновляются до объекта, содержащего tabid установленный в 0.
  4. Если вкладка перезагружена, она сначала выгружается и возобновляется. Поскольку существует tabid ключа хранилища tabid, а также ключ tabs локального хранилища с tabid клавишей tabid локальное хранилище не очищается.
  5. Когда браузер выгружен, все хранилище сессии будет очищено. При возобновлении tabid хранилища tabid больше не существует, и будет создан новый tabid. Так как в локальном хранилище нет tabid для этого tabid или любого другого tabid (все сеансы были закрыты), он очищен.
  6. При новой созданной вкладке, новые tabid генерируются в памяти сессии, но так как по крайней мере один tabs [ tabid ] существует, локальное хранилище не очищается
  • 1
    Однако, если происходит сбой браузера, window.onbeforeunload не будет вызываться, и для локальных tabs[tabid] не будет установлено значение 0 =>, локальное хранилище больше никогда не будет очищено. Я думаю, что сторожевой таймер был бы более уместным в этом случае, вместо записи 1 при загрузке вкладки, вы должны написать текущую метку времени. Затем в части сокращения вы должны установить задержку, поскольку эта временная метка не слишком велика, или заменить ее на 0, если она есть. Таким образом, вы не onbeforeunload от фактического вызова onbeforeunload . Вкладке просто необходимо время от времени переустанавливать сторожевой таймер для поддержания существования локального хранилища.
0

Это старый вопрос, но, похоже, ни один из приведенных выше ответов не идеален.

В случае, если вы хотите сохранить аутентификацию или любую конфиденциальную информацию, которая уничтожается только при закрытом браузере, вы можете положиться на sessionStorage и localStorage для передачи сообщений между вкладками.

По сути, идея заключается в следующем:

  1. Вы загружаете из предыдущей открытой вкладки, поэтому и ваши localStorage и sessionStorage пусты (если нет, вы можете очистить localStorage). Вам нужно зарегистрировать прослушиватель событий сообщения в localStorage.
  2. Пользователь аутентифицирует/создает конфиденциальную информацию на этой вкладке (или любой другой вкладке, открытой на вашем домене).
  3. Вы обновляете sessionStorage для хранения конфиденциальной информации и используете localStorage для хранения этой информации, а затем удаляете ее (здесь вам не нужно время, так как событие было поставлено в очередь при изменении данных). Любая другая вкладка, открытая в то время, будет sessionStorage по событию сообщения и обновит свой sessionStorage с конфиденциальной информацией.
  4. Если пользователь откроет новую вкладку в вашем домене, его sessionStorage будет пустым. Код должен будет установить ключ в localStorage (например: req). Любая (все) другая вкладка будет вызвана обратно в событии сообщения, увидит этот ключ и может ответить секретной информацией из их sessionStorage (как в 3), если они есть.

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

Вот демонстрация этой концепции: http://jsfiddle.net/oypdwxz7/2/

  • 0
    Спасибо за правку xryl669, вы сделали хороший вывод. Когда я сейчас думаю об этом, возможно, было бы лучше использовать веб-работника с общим доступом? developer.mozilla.org/en-US/docs/Web/API/SharedWorker, если текущая поддержка браузера не является проблемой
  • 0
    Да, вы можете использовать SharedWorker или BroadcastChannel (или подобное локальное хранилище), хотя первые два недоступны в Edge. В основном, любой метод, который является кросс-таблицей, кросс-окном, будет работать. Трудность заключается в том, чтобы найти тот, который работает везде с минимумом хлопот.
-4

Вы можете попробовать следующий код для удаления локального хранилища:

delete localStorage.myPageDataArr;
  • 29
    Это неправильный способ удаления ключа localStorage. Вы должны использовать localStorage.removeItem(key); удалить ключ.
  • 1
    Следует использовать localStorage.removeItem (ключ); не ключевое слово delete.
Показать ещё 4 комментария
-5

Это будет работать как шарм, если вы используете AngularJS

$localStorage.$reset(); 

Ещё вопросы

Сообщество Overcoder
Наверх
Меню