如何实现localStorage的过期机制?

4,331 阅读3分钟

「这是我参与2022首次更文挑战的第22天,活动详情查看:2022首次更文挑战

前言

我们都知道cookie存储的数据是可以添加过期时间属性(Expires/Max-Age),实现过期的。 那么,LocalStrorage、sessionStrorage可以设置过期吗??

带着这样的疑问,我们一层层剥开其神秘的面纱。

cookie过期机制

我们知道Expires和Max-age都可以设置cookie的过期时间,那么两者存在什么样的异同点呢?

expires和max-age的区别

Expires 设置的是绝对值,即直接设置当前cookie在什么时候过期。 就像下面图中的这样, GMT格式。 image.png

  • Expires在HTTP/1.0中已经定义
  • max-age在HTTP/1.1中才有定义,为了向下兼容,仅使用max-age不够;

Expires 设置一个绝对值,至少会带来两个方面的问题:

  1. 客户端和服务端时间不同步的问题。往往表现为时区不同、客户端时间可被用户自由修改。
  2. 很容易在配置后忘记具体的过期时间,导致过期来临出现浪涌现象(我的理解应该是同时大批量更新的问题)。

Max-Age代表存活时间,记录的是一个相对时间(例如 6000s),起始时间点是服务器记录的requet-time。

我们看到除了上面提到的两个值,还有 session, 这个值代表的意思就是在当前连接下,关闭浏览器窗口、断开与服务连接,该数据即失效。

image.png

localStorage 数据过期

localstorage本身是没有过期机制的,不过我们可以通过其他手段来扩展,使其能够满足我们的数据过期的需求。

需求分析:

  1. 存入数据时,顺带传入过去时间;
  2. 获取数据时,判断当前是否过期,过期返回 undefined; 否则正常返回数据。

动手实践

localStorage 和 sessionStorage 都继承自 Storage 对象, 所以我们可以扩展Storage原型方法。

setStorageWithAge(key, value, age) 方法, 接收三个参数,第三个参数代表最大过期时间,我们这里参考 cookie的 Max-Age 的实现,用相对时间来做。

getStorageWithAge(key),内部直接判断时间是否过期来返回对应的值。

代码实现:

Storage.prototype.setStorageWithAge = (key, value, age) => {
    if (isNaN(age) || age < 1) throw new Error("age must be a number");
    const obj = {
        data: value, //存储值
        time: Date.now(), //存值时间戳
        maxAge: age, //过期时间
    };
    localStorage.setItem(key, JSON.stringify(obj));
};

Storage.prototype.getStorageWithAge = key => {
    const { data, time, maxAge } = JSON.parse(localStorage.getItem(key));
    if (time + maxAge < Date.now()) {
        localStorage.removeItem(key);
        return undefined;
    }
    return data;
};

尝试调用:

localStorage.setStorageWithAge('amingxiansen', '测试过期时间', 30000);
localStorage.getStorageWithAge('amingxiansen');

image.png

设定30s的过期时间,过期之前和过期之后获取到的结果。

总结

Storage只是浏览器的一种存储方案,除此之外还有IndexDB、WebSQL等。

这种实现数据过期机制的思路比较通用,可以扩展到其他需要设置数据过期的场景下。

我是Back_kk,前端表单工程师,喜欢本文请动动手指点个👍🏻,我将不胜感激。

参考文章

  1. localStorage设置有效期、过期时间