Когда истекает срок действия элементов в локальном хранилище HTML5?

268

Как долго хранятся данные, хранящиеся в localStorage (как часть хранилища DOM в HTML5)? Могу ли я установить время истечения для данных, которые я ввел в localStorage?

  • 1
    не используйте localStorage, если это возможно, потому что срок действия никогда не истекает автоматически, там вы можете использовать sessionStorage, это более предпочтительно
Теги:
local-storage

16 ответов

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

Не возможно указать срок действия. Это полностью зависит от пользователя.

https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

Конечно, возможно, что что-то, что ваше приложение хранит на клиенте, может не появиться там позже. Пользователь может явно избавиться от локального хранилища, или браузер может столкнуться с соображениями пространства. Хорошо программировать в обороне. Как правило, однако, вещи остаются "навсегда", основываясь на каком-то практическом определении этого слова.

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

  • 1
    Так может ли пользователь рассчитывать на доступность данных, скажем, через год? Может ли разработчик рассчитывать на доступность данных, если пользователь явно не удалит их?
  • 6
    @AndresRiofrio Я не могу найти документацию от Mozilla, Microsoft или W3C, которая предусматривает какой-либо обязательный срок действия. Таким образом, я думаю, что ответ заключается в том, что да, пользовательский агент должен хранить сохраненные данные всегда или до тех пор, пока пользователь явно не попросит их удалить (или я предполагаю, что ваше собственное приложение не удалит свои собственные вещи).
Показать ещё 4 комментария
206

Я бы предложил сохранить временную метку в объекте, который вы храните в локальном хранилище

var object = {value: "value", timestamp: new Date().getTime()}
localStorage.setItem("key", JSON.stringify(object));

Вы можете проанализировать объект, получить отметку времени и сравнить с текущей датой и, при необходимости, обновить значение объекта.

var object = JSON.parse(localStorage.getItem("key")),
    dateString = object.timestamp,
    now = new Date().getTime().toString();

compareTime(dateString, now); //to implement
  • 3
    Ну, даже если клиентское время не согласовано, вы все равно можете найти способ использовать серверное время вместо этого. Как эхом метка времени в div.
  • 0
    Будете ли вы анализировать и сравнивать временную метку во временном интервале (например, settimout для каждых 5 секунд) или для каждого запроса, который клиент отправляет на сервер?
Показать ещё 1 комментарий
35

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

Из readme:

lscache.set

Stores the value in localStorage. Expires after specified number of minutes.

Arguments
key (string)
value (Object|string)
time (number: optional)

Это единственное реальное различие между обычными методами хранения. Получить, удалить и т.д. То же самое.

Если вам не нужна такая большая функциональность, вы можете просто сохранить отметку времени со значением (через JSON) и проверить его на срок.

Примечательно, что есть веская причина, почему локальное хранилище остается для пользователя. Но такие вещи, как lscache, пригождаются, когда вам нужно хранить крайне временные данные.

  • 1
    Я нашел это с помощью поиска, поэтому я потратил немного времени, чтобы сделать его «правильным». Надеюсь, ты не против :)
  • 0
    Спасибо! Это потрясающе для того, что мне нужно - данные просто должны быть там на случай, если пользователь сделает болван или браузер закроется, прежде чем он сохранит свою работу, но для куки-файлов будет слишком много данных. Я использую его в сочетании с pieroxy.net/blog/pages/lz-string/index.html .
27

Brynner Ferreira, принес хороший момент: сохранение ключа для сиблинга, где находится информация об истечении срока. Таким образом, , если у вас есть большое количество ключей, или если ваши значения являются большими объектами Json, вам не нужно анализировать их для доступа к метке времени.

здесь следует улучшенная версия:

 /*  removeStorage: removes a key from localStorage and its sibling expiracy key
    params:
        key <string>     : localStorage key to remove
    returns:
        <boolean> : telling if operation succeeded
 */
 function removeStorage(name) {
    try {
        localStorage.removeItem(name);
        localStorage.removeItem(name + '_expiresIn');
    } catch(e) {
        console.log('removeStorage: Error removing key ['+ key + '] from localStorage: ' + JSON.stringify(e) );
        return false;
    }
    return true;
}
/*  getStorage: retrieves a key from localStorage previously set with setStorage().
    params:
        key <string> : localStorage key
    returns:
        <string> : value of localStorage key
        null : in case of expired key or failure
 */
function getStorage(key) {

    var now = Date.now();  //epoch time, lets deal only with integer
    // set expiration for storage
    var expiresIn = localStorage.getItem(key+'_expiresIn');
    if (expiresIn===undefined || expiresIn===null) { expiresIn = 0; }

    if (expiresIn < now) {// Expired
        removeStorage(key);
        return null;
    } else {
        try {
            var value = localStorage.getItem(key);
            return value;
        } catch(e) {
            console.log('getStorage: Error reading key ['+ key + '] from localStorage: ' + JSON.stringify(e) );
            return null;
        }
    }
}
/*  setStorage: writes a key into localStorage setting a expire time
    params:
        key <string>     : localStorage key
        value <string>   : localStorage value
        expires <number> : number of seconds from now to expire the key
    returns:
        <boolean> : telling if operation succeeded
 */
function setStorage(key, value, expires) {

    if (expires===undefined || expires===null) {
        expires = (24*60*60);  // default: seconds for 1 day
    } else {
        expires = Math.abs(expires); //make sure it positive
    }

    var now = Date.now();  //millisecs since epoch time, lets deal only with integer
    var schedule = now + expires*1000; 
    try {
        localStorage.setItem(key, value);
        localStorage.setItem(key + '_expiresIn', schedule);
    } catch(e) {
        console.log('setStorage: Error setting key ['+ key + '] in localStorage: ' + JSON.stringify(e) );
        return false;
    }
    return true;
}
  • 0
    В setStorage (), строка else не должна быть expires = Math.abs(1000*expires); //make sure it's positive ?
21

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

Пример в jQuery:

if (!$.cookie('your_key') || !localStorage.getItem('your_key')) {
    //get your_data from server, then...
    localStorage.setItem('your_key', 'your_data' );
    $.cookie('your_key', 1);
} else {
    var your_data = localStorage.getItem('your_key');
}
// do stuff with your_data

В этом примере устанавливается cookie с параметром по умолчанию, который истекает, когда браузер закрыт. Таким образом, когда браузер закрыт и снова открывается, локальное хранилище данных для ваших_данных будет обновлено вызовом на стороне сервера.

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

  • 0
    Файлы cookie можно очистить и, что еще хуже, можно полностью отключить.
  • 1
    Мне больше всего нравится это решение, потому что оно позволяет браузеру справляться с истечением срока действия нашего решения для хранения без необходимости использования других библиотек или управления локальными датами хранения вручную.
Показать ещё 1 комментарий
14

Здесь настоятельно рекомендуется использовать sessionStorage

  • это то же самое, что localStorage, но уничтожить, когда сессия уничтожена/браузер закрыт
  • sessionStorage также полезен для уменьшения сетевого трафика против cookie

для использования заданного значения

sessionStorage.setItem("key","my value");

для получения ценности использования

var value = sessionStorage.getItem("key");

Нажмите здесь для просмотра API

все способы для набора

  sessionStorage.key = "my val";
  sessionStorage["key"] = "my val";
  sessionStorage.setItem("key","my value");

все пути для получения

  var value = sessionStorage.key;
  var value = sessionStorage["key"];
  var value = sessionStorage.getItem("key");
  • 1
    Спас мой день! Полностью забыл про sessionStorage. Спасибо
  • 0
    Ваш самый желанный :-)
Показать ещё 1 комментарий
13

Жизненный цикл контролируется приложением/пользователем.

Из стандарт:

Пользовательские агенты должны истекать из локальных областей хранения только по соображениям безопасности или по запросу пользователя. Пользовательским агентам всегда следует избегать удаления данных, а script, которые могут получить доступ к этим данным.

9
// Functions
function removeHtmlStorage(name) {
    localStorage.removeItem(name);
    localStorage.removeItem(name+'_time');
}

function setHtmlStorage(name, value, expires) {

    if (expires==undefined || expires=='null') { var expires = 3600; } // default: 1h

    var date = new Date();
    var schedule = Math.round((date.setSeconds(date.getSeconds()+expires))/1000);

    localStorage.setItem(name, value);
    localStorage.setItem(name+'_time', schedule);
}

function statusHtmlStorage(name) {

    var date = new Date();
    var current = Math.round(+date/1000);

    // Get Schedule
    var stored_time = localStorage.getItem(name+'_time');
    if (stored_time==undefined || stored_time=='null') { var stored_time = 0; }

    // Expired
    if (stored_time < current) {

        // Remove
        removeHtmlStorage(name);

        return 0;

    } else {

        return 1;
    }
}

// Status
var cache_status = statusHtmlStorage('cache_name');

// Has Data
if (cache_status == 1) {

    // Get Cache
    var data = localStorage.getItem('cache_name');
    alert(data);

// Expired or Empty Cache
} else {

    // Get Data
    var data = 'Pay in cash :)';
    alert(data);

    // Set Cache (30 seconds)
    if (cache) { setHtmlStorage('cache_name', data, 30); }

}
  • 4
    Мне нравится этот подход, так как он не требует предварительного анализа данных.
  • 0
    в функции statusHtmlStorage вы имели в виду var date = Date.now(); ???
9

Из черновика W3C:

Пользовательские агенты должны истекать из локальных областей хранения только по соображениям безопасности или по запросу пользователя. Пользовательским агентам всегда следует избегать удаления данных, а script, которые могут получить доступ к этим данным.

Вы хотите делать свои обновления в своем расписании, используя setItem (ключ, значение); который либо добавит, либо обновит данный ключ новыми данными.

  • 0
    Хм ... может быть, было бы неплохо перечислить дату как часть данных? Или, может быть, каждый раз при изменении данных используется другой ключ.
3

Если кто-то использует jStorage Plugin jQuery, он может добавить истечение с помощью функции setTTL, если плагин jStorage

$.jStorage.set('myLocalVar', "some value");
$.jStorage.setTTL("myLocalVar", 24*60*60*1000); // 24 Hr.
2

Если кто-то все еще ищет быстрое решение и не хочет зависимостей, таких как jquery и т.д. Я написал мини-lib, которые добавляют срок годности в локальный/сеансовый/пользовательский накопитель, вы можете найти его с исходным кодом здесь:

https://github.com/RonenNess/ExpiredStorage

1

Подход @sebarmeli является лучшим, на мой взгляд, но если вы хотите, чтобы данные сохранялись для жизни сеанса, тогда sessionStorage, вероятно, лучший вариант:

Это глобальный объект (sessionStorage), который поддерживает область хранения которые доступны для продолжительности сеанса страницы. Сеанс страницы длится до тех пор, пока браузер открыт и выживет на странице перезагружает и восстанавливает. Открытие страницы в новой вкладке или окне приведет к новый сеанс.

MDN: sessionStorage

1

Обходной путь с использованием angular и localforage:

angular.module('app').service('cacheService', function() {

  return {
    set: function(key, value, expireTimeInSeconds) {
      return localforage.setItem(key, {
        data: value,
        timestamp: new Date().getTime(),
        expireTimeInMilliseconds: expireTimeInSeconds * 1000
      })
    },
    get: function(key) {
      return localforage.getItem(key).then(function(item) {
        if(!item || new Date().getTime() > (item.timestamp + item.expireTimeInMilliseconds)) {
          return null
        } else {
          return item.data
        }
      })
    }
  }

})
  • 0
    Это использует localForage: github.com/mozilla/localForage
  • 0
    Я проверил сайт и не вижу ключа «expireTimeInMilliseconds» в их API. Это недокументированная / неподдерживаемая настройка?
Показать ещё 3 комментария
0

Это работает.. Персональный опыт.

setTimeout(function(){ localStorage.clear(); }, 10000);
0

В интересах поисковиков:

Как и Фернандо, я не хотел добавлять нагрузку json, когда сохраненные значения были простыми. Мне просто нужно было отслеживать взаимодействие с пользовательским интерфейсом и держать данные релевантными (например, как пользователь использовал сайт электронной торговли перед проверкой).

Это не будет соответствовать всем критериям, но мы надеемся, что это будет быстрый экземпляр + вставить стартер для кого-то и сохранить добавление другой библиотеки.

ПРИМЕЧАНИЕ. Это не очень хорошо, если вам нужно получить элементы отдельно.

// Addition
if(window.localStorage){
    localStorage.setItem('myapp-' + new Date().getTime(), 'my value');
}

// Removal of all expired items
if(window.localStorage){

    // two mins - (1000 * 60 * 20) would be 20 mins
    var expiryTime = new Date().getTime() - (1000 * 60 * 2);

    var deleteRows = [];
    for(var i=0; i < localStorage.length; i++){
        var key = localStorage.key(i);
        var partsArray = key.split('-');
        // The last value will be a timestamp
        var lastRow = partsArray[partsArray.length - 1];

        if(lastRow && parseInt(lastRow) < expiryTime){
            deleteRows.push(key);
        }
    }
    // delete old data
    for(var j=0; j < deleteRows.length; j++){
        localStorage.removeItem(deleteRows[j]);
    }
}
-1

Вы можете смешивать java и javascript в jsp. Здесь моя логика

//Setting Expiry date after 1 month
    <%
                   int no_of_days =30;
                   Date dNow = new Date();
                   SimpleDateFormat ft = new SimpleDateFormat("dd-MM-yyyy");
                   Calendar cal = Calendar.getInstance();

                   cal.add(Calendar.DATE, no_of_days);
                   Date dateAfter1Month= cal.getTime();
                   String fromDate = ft.format(dateAfter1Month);

                %>

                var expiryDate = "<%=fromDate%>";

                localStorage.setItem("expiry",expiryDate);

//Checking Date is matching

<%
           Date dNow = new Date();
           SimpleDateFormat ft = new SimpleDateFormat("dd-MM-yyyy");
           String curDate = ft.format(dNow);

        %>

        var curDate = "<%=curDate%>";
        var expiryDate=localStorage.getItem("expiry");
        if(curDate=expiryDate){

            localStorage.removeItem("expiry");
        }

Ещё вопросы

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