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

IT技术 javascript html local-storage
2021-01-10 19:13:32

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

6个回答

我建议将时间戳存储在您存储在 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

或者,您可以使用像localstorage-slim.js这样的轻量级包装器来为您处理这个问题。

您会在一个时间间隔内(例如settimout每 5 秒)还是为客户端发送到服务器的每个请求解析和比较时间戳
2021-03-17 19:13:32
更好的方法是比较每个用户请求的日期
2021-03-30 19:13:32
我建议使用Date.now()而不是new Date().getTime().
2021-03-30 19:13:32
好吧,即使客户端时间不一致,您仍然可以找到一种使用服务器时间的方法。就像将时间戳回显到 div 中一样。
2021-03-31 19:13:32

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

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

当然,您的应用程序存储在客户端上的某些内容可能稍后不存在。用户可以明确地摆脱本地存储,否则浏览器可能会遇到空间问题。防御性编程很好。然而,一般情况下,根据该词的一些实际定义,事情仍然是“永远”的。

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

@AndresRiofrio 我找不到来自 Mozilla 或 Microsoft 或 W3C 的任何规定任何类型的强制到期的文档。因此,我认为答案是肯定的,用户代理应该永远保留存储的内容,或者直到用户明确请求将其删除(或者我猜直到您自己的应用程序删除了自己的内容)。
2021-03-11 19:13:32
那么,用户可以指望一年后可用的数据吗?除非用户明确删除数据,否则开发人员能否指望数据可用
2021-03-12 19:13:32
这也意味着您的浏览器不断增长。您使用一次应用程序,它会将其内容存储在您的浏览器中,并且会永远留在那里......
2021-03-29 19:13:32
每个网站可以存储的 localStorage 数据量约为 10mb,但一般站点不会存储多于几个字符串,所以我不介意存储空间
2021-04-05 19:13:32
Firefox在此处有记录在案的驱逐政策
2021-04-05 19:13:32

您可以使用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 之类的东西确实会派上用场。

谢谢!这对于我需要的东西来说太棒了 - 数据只需要在那里,以防用户在保存他们的工作之前发出嘘声或浏览器关闭,但是 cookie 的数据太多。我将它与pieroxy.net/blog/pages/lz-string/index.html结合使用
2021-03-29 19:13:32

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;
}
只是一个getStorage电话如果您尝试直接访问_expiresIn密钥版本,则该密钥将成为..._expiresIn_expiresIn当然不存在的..._expiresIn密钥,因此它会删除原始密钥,然后下次访问原始密钥时,该密钥..._expiresIn不存在并删除原始密钥钥匙。当我在我的一个项目中遇到这个问题时,我建议为此设置陷阱。 if(key.indexOf('_expiresIn') > -1) { return localStorage.getItem(key); }
2021-03-17 19:13:32
在 setStorage() 中,该else不应该expires = Math.abs(1000*expires); //make sure it's positive
2021-03-18 19:13:32

虽然本地存储不提供过期机制,但 cookie 提供。简单地将本地存储密钥与 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 设置为在浏览器关闭时过期。因此,当浏览器关闭并重新打开时,your_data 的本地数据存储会通过服务器端调用刷新。

请注意,这与删除本地数据存储并不完全相同,而是在 cookie 过期时更新本地数据存储。但是,如果您的主要目标是能够存储超过 4K 的客户端(cookie 大小的限制),则 cookie 和本地存储的这种配对将帮助您使用与 cookie 相同的到期参数来完成更大的存储大小.

我最喜欢这个解决方案,因为它让浏览器可以处理我们的存储解决方案的到期,而无需使用其他库或手动管理本地存储日期。
2021-03-28 19:13:32
Cookie 可以被清除,更糟糕的是,可以完全关闭。
2021-04-04 19:13:32
请记住,在每个请求中都会发送 Cookie。
2021-04-10 19:13:32