Javascript HTML5本地存储中的项目何时过期?

Javascript HTML5本地存储中的项目何时过期?,javascript,html,local-storage,Javascript,Html,Local Storage,作为HTML5中DOM存储的一部分,localStorage中存储的数据可用多长时间?我可以为放入本地存储的数据设置过期时间吗?无法指定过期时间。这完全取决于用户 当然,应用程序存储在客户机上的某些东西可能以后就不存在了。用户可以明确地摆脱本地存储,或者浏览器可能会遇到空间问题。防御性的编程是很好的。然而,通常情况下,基于这个词的一些实际定义,事物永远存在 编辑-显然,如果您自己的应用程序认为内容太旧,它可以主动删除这些内容。也就是说,您可以在已保存的内容中明确包含某种时间戳,然后稍后使用该时间

作为HTML5中DOM存储的一部分,localStorage中存储的数据可用多长时间?我可以为放入本地存储的数据设置过期时间吗?

无法指定过期时间。这完全取决于用户

当然,应用程序存储在客户机上的某些东西可能以后就不存在了。用户可以明确地摆脱本地存储,或者浏览器可能会遇到空间问题。防御性的编程是很好的。然而,通常情况下,基于这个词的一些实际定义,事物永远存在


编辑-显然,如果您自己的应用程序认为内容太旧,它可以主动删除这些内容。也就是说,您可以在已保存的内容中明确包含某种时间戳,然后稍后使用该时间戳来决定是否应刷新信息。

生命周期由应用程序/用户控制

从:

只有出于安全原因或在用户请求时,用户代理才能使本地存储区域中的数据过期。当可以访问数据的脚本正在运行时,用户代理应始终避免删除数据

来自W3C草案:

只有出于安全原因或在用户请求时,用户代理才能使本地存储区域中的数据过期。当可以访问数据的脚本正在运行时,用户代理应始终避免删除数据


您将希望使用setItemkey、value对日程进行更新;这将使用新数据添加或更新给定的密钥。

我建议将时间戳存储在存储在localStorage中的对象中

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
你可以用。它会自动为您处理此问题,包括存储大小超过限制的实例。如果发生这种情况,它将开始修剪最接近其指定到期日的项

自述文件:

这是常规存储方法之间唯一的真正区别。获取、移除等相同的工作

若您不需要那个么多功能,只需通过JSON存储一个带有值的时间戳并检查它是否过期


值得注意的是,本地存储留给用户有一个很好的理由。但是,当您需要存储非常临时的数据时,像lscache这样的东西确实会派上用场

虽然本地存储不提供过期机制,但cookie提供。只需将本地存储密钥与cookie配对,就可以轻松地确保本地存储可以使用与cookie相同的过期参数进行更新

// 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); }

}
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过期时更新本地数据存储。但是,如果您的主要目标是能够在客户端存储超过4K的cookie大小限制,那么cookie和本地存储的这种配对将帮助您使用与cookie相同的过期参数来实现更大的存储大小。

使用angular和LocalFound的变通方法:

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
        }
      })
    }
  }

})

@在我看来,sebarmeli的方法是最好的,但如果您只希望数据在会话的整个生命周期内保持不变,那么会话存储可能是更好的选择:

这是维护存储区域的全局对象会话存储 这在页面会话期间可用。页面会话 只要浏览器处于打开状态并在整个页面上继续存在,该状态就会持续 重新加载和恢复。在新选项卡或窗口中打开页面将导致 将启动一个新会话


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's 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;
}

为了搜索者的利益:

像Fernando一样,当存储的值很简单时,我不想添加json负载。我只需要跟踪一些UI交互,并保持数据的相关性,例如用户在结账前如何使用电子商务网站

这将不会满足每个人的标准,但有望成为一个快速复制+粘贴初学者的人,并保存添加另一个库

注意:如果您需要单独检索项目,这将不好

// 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]);
    }
}

如果有人使用jQuery的jStorage插件,如果jStorage插件可用setTTL函数添加到期日

$.jStorage.set('myLocalVar', "some value");
$.jStorage.setTTL("myLocalVar", 24*60*60*1000); // 24 Hr.
这里强烈建议使用sessionStorage

它与localStorage相同,但在会话销毁/浏览器关闭时销毁 此外,本地存储还可以在会话存储时在选项卡之间共享 只能在当前选项卡中使用,但值不会在刷新页面或更改页面上更改 会话存储也有助于减少针对cookie的网络流量 供设定值使用

为了得到有价值的使用

set的所有方法都是

获取的所有方法都是


如果有人仍在寻找快速解决方案,并且不想要jquery等依赖项,我编写了一个小型库,将过期添加到本地/会话/自定义存储,您可以在这里找到它的源代码:

你可以试试这个

var hours = 24; // Reset when storage is more than 24hours
var now = Date.now();
var setupTime = localStorage.getItem('setupTime');
if (setupTime == null) {
     localStorage.setItem('setupTime', now)
} else if (now - setupTime > hours*60*60*1000) {
    localStorage.clear()
    localStorage.setItem('setupTime', now);
}

如果您熟悉浏览器,您就知道没有提供到期时间的规定。但是,我们可以使用Javascript添加一个TTL生存时间,以便在经过一定时间后使locaStorage中的项目无效

function setLocalStorageItem(key, value, ttl) {
    // `item` is an object which contains the original value
    // as well as the time when it's supposed to expire
    let item = {
        value: value,
        expiry: ttl ? Date.now() + ttl : null
    };

    localStorage.setItem(key, JSON.stringify(item));
}

function getLocalStorageItem(key) {
    let item = localStorage.getItem(key);
    
    // if the item doesn't exist, return null
    if (!item) return null;

    item = JSON.parse(item);
    // compare the expiry time of the item with the current time
    if (item.expiry && Date.now() > item.expiry) {
        // If the item is expired, delete the item from storage and return null
        localStorage.removeItem(key);

        return null;
    }
    
    return item.value;
}
Javascript localStorage没有任何设置过期时间的选项

然后我使用这些函数来检查支持、设置和获取

而且似乎效果不错:

隐马尔可夫模型。。。也许将日期列为数据的一部分是个好主意?或者每次数据更改时使用不同的键。因此,用户可以指望在一年后数据可用吗?除非用户明确删除数据,否则开发人员能指望数据可用吗?@AndresRiofrio我在Mozilla、Microsoft或W3C中找不到任何规定强制过期的文档。因此,我认为答案是肯定的,用户代理应该永远保留存储的内容,或者直到用户明确要求删除它,或者我猜直到您自己的应用程序删除它自己的内容。这也意味着您的浏览器不断增长。你使用一个应用程序一次,它会在你的浏览器中存储它的内容,并且永远保持在那里……每个网站可以存储的本地存储数据量约为10mb,但一个平均网站存储的数据不会超过几个字符串,所以我不介意存储空间Firefox有一个文档。我检查了该网站,我在他们的API中没有看到任何“ExpireTimeInMillionSeconds”键。这是一个未记录/不支持的设置吗?@PhilOlson这是我使用LocalFough使用的自定义实现。ExpireTimeInMillSeconds不是某个LocalFlow属性,而是一个用于检查存储数据是否需要过期的变量。检查我的示例中的get函数定义。哇,localfough不是我所期望的轻量级小助手类。我喜欢这种方法,因为它不需要首先解析数据。谢谢,我还采用了这种方法来解决我的问题。此外,每次状态检查通过时,我都会更新存储的_,这样我就不会在用户在过去一个小时内积极使用GUI时意外注销用户。只有当页面未使用一小时后,我才希望它自动注销。好吧,即使客户端时间不一致,你仍然可以找到一种使用服务器时间的方法。就像将时间戳回显到一个div中一样。您会在一个时间间隔内解析和比较时间戳吗?例如,每5秒设置一次timeout,还是为客户端发送到服务器的每个请求设置timeout?更好的方法是比较每个用户请求的日期。我建议使用Date.now而不是new Date.getTime.Cookies,而且更糟糕的是,可以完全关闭。我最喜欢此解决方案,因为它允许浏览器处理存储解决方案的过期,而无需使用其他库或手动管理本地存储日期。请记住,每次请求都会发送Cookies。谢谢!这对于我所需要的东西来说太棒了——数据只需要在那里,以防用户在保存工作之前发出booboo或浏览器关闭,但是cookie中的数据太多了。在setStorage中,else行不应该是expires=Math.abs1000*expires//确保它是肯定的?只是getStorage调用的一个要点。如果您试图直接访问密钥的_expiresIn版本,则该密钥将变为…_expiresIn\u expiresIn,当然该密钥不存在,因此它将删除原始…_expiresIn密钥,然后下次访问原始密钥时,该…_expiresIn不存在并删除原始密钥。当我在我的一个项目中遇到这个问题时,我建议使用陷阱。如果key.indexOf''u expiresIn'>-1{return localStorage.getItemkey;}如果可能的话不要使用localStorage,因为它永远不会自动过期,在那里你可以使用sessionStorage。更可取的是注意sessionStorage不能在选项卡之间共享数据。你可能需要一个函数来强制删除用户设备中所有过期的变量吗?!很不错的。我用过
var value = sessionStorage.getItem("key");
  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");
var hours = 24; // Reset when storage is more than 24hours
var now = Date.now();
var setupTime = localStorage.getItem('setupTime');
if (setupTime == null) {
     localStorage.setItem('setupTime', now)
} else if (now - setupTime > hours*60*60*1000) {
    localStorage.clear()
    localStorage.setItem('setupTime', now);
}
function setLocalStorageItem(key, value, ttl) {
    // `item` is an object which contains the original value
    // as well as the time when it's supposed to expire
    let item = {
        value: value,
        expiry: ttl ? Date.now() + ttl : null
    };

    localStorage.setItem(key, JSON.stringify(item));
}

function getLocalStorageItem(key) {
    let item = localStorage.getItem(key);
    
    // if the item doesn't exist, return null
    if (!item) return null;

    item = JSON.parse(item);
    // compare the expiry time of the item with the current time
    if (item.expiry && Date.now() > item.expiry) {
        // If the item is expired, delete the item from storage and return null
        localStorage.removeItem(key);

        return null;
    }
    
    return item.value;
}
function ls_support(){
    return "localStorage" in window&&window["localStorage"]!==null;
}

function lsset(key,val,exp){
    if(ls_support()){
        if(!exp) exp=600;// = 10 minutes Default
        localStorage[key]=
            JSON.stringify({
                "val":val,
                "exp":~~((new Date()).getTime()/1000)+exp
            });
    }
}

function lsget(key){
    if(ls_support()){
        str=localStorage[key];
        if("undefined"!=typeof(str)&&str.length){
            try{// is json or not
                json=JSON.parse(str);
            }catch(e){// if variable not set via lsset func
                //json.exp=false;// will return null
                return str;// will return original variable
            }
            if(json.exp){// variable setted via lsset func
                if(~~((new Date()).getTime()/1000)>json.exp){// expired
                    delete localStorage[key];
                }else{
                    return json.val;
                }
            }
        }
    }
    return null;
}