如何给 localStorage 设置一个有效期? - V2EX
爱意满满的作品展示区。
southSu

如何给 localStorage 设置一个有效期?

  •  
  •   southSu
    meibin08 Nov 7, 2018 5145 views
    This topic created in 2742 days ago, the information mentioned may be changed or developed.

    如何给 localStorage 设置一个有效期

    引言

      这个话题其实在上次分享<小程序填坑记里讲过了>已经讲过(大佬可绕过哦~),但后来群里 /评论都有些同学,提到了一些疑问,问能否单独整理一篇更为详细的分享,讲解一下细节和完善提到的不足,如是有了下文。

    这里是@IT平头哥联盟,我是首席填坑官苏南,用心分享 做有温度的攻城狮。 公 Z 号:honeyBadger8,群:912594095

    思考点

    从我们接触前端起,第一个熟悉的存储相关的 Cookie 或者来分析我们生活中密切相关的淘宝、物流、闹钟等事物来说起吧,

    • Cookie 从你设置的时候,就会给个时间,不设置默认会话结束就过期;
    • 淘宝购物 从你下单付款起,就会给这件货物设置一个收货期限时间,过了这个时间自动认为你收货(即订单结束);
    • 闹钟 你设置的提醒时间,其实也就是它的过期时间;
    • 再比如与您每天切身相关的产品需求,过完需求,你给出的上线时间,也就是这个需求的过期时间;
    • 再通俗点讲,您今年的生日过完到明年生日之间也是相当于设置了有效期时间;

    !> 以上种种,我们能得出一个结论任何一件事、一个行为动作,都有一个时间、一个节点,甚至我们可以黑localStorage,就是一个完善的 API,为什么不能给一个设置过期的机制,因为sessionStorageCookie并不能满足我们实际的需求。

    实现思路

    抱歉,黑localStorage不完善,有点夸张了,综合上述的总结,问题就简单了,给localStorage一个过期时间,一切就都 so easy ?到底是不是,来看看具体的实现吧:

    简单回顾

    //示例一: localStorage.setItem('test',1234567); let test = localStorage.getItem('test'); console.log(typeof test, test); //示例二: localStorage['name'] = '苏南'; console.log(localStorage['name']); /* 输出: "1234567" ,'苏南', 这里要注意,1234567 存进去时是 number 取出来就成 string 了 */ 

    重写 set(存入) 方法:

    • 首先有三个参数 key、value、expired,分别对应 键、值、过期时间,
    • 过期时间的单位可以自由发挥,小时、分钟、天都可以,
    • 注意点:存储的值可能是数组 /对象,不能直接存储,需要转换 JSON.stringify
    • 这个时间如何设置呢?在这个值存入的时候在键(key)的基础上扩展一个字段,如:key+'expires',而它的值为当前 时间戳 + expired 过期时间
    • 具体来看一下代码
     set(key, value, expired) { /* * set 存储方法 * @ param {String} key 键 * @ param {String} value 值, * @ param {String} expired 过期时间,以分钟为单位,非必须 * @ 由 @IT平头哥联盟-首席填坑官苏南 分享 */ let source = this.source; source[key] = JSON.stringify(value); if (expired){ source[`${key}__expires__`] = Date.now() + 1000*60*expired }; return value; } 

    重写 get(获取) 方法:

    • 获取数据时,先判断之前存储的时间有效期,与当前的时间进行对比;
    • 但存储时expired为非必须参数,所以默认为当前时间+1,即长期有效;
    • 如果存储时有设置过期时间,且在获取的时候发现已经小于当前时间戳,则执行删除操作,并返回空值;
    • 注意点:存储的值可能是数组 /对象,取出后不能直接返回,需要转换 JSON.parse
    • 具体来看一下代码
    get(key) { /* * get 获取方法 * @ param {String} key 键 * @ param {String} expired 存储时为非必须字段,所以有可能取不到,默认为 Date.now+1 * @ 由 @IT平头哥联盟-首席填坑官苏南 分享 */ const source = this.source, expired = source[`${key}__expires__`]||Date.now+1; const now = Date.now(); if ( now >= expired ) { this.remove(key); return; } const value = source[key] ? JSON.parse(source[key]) : source[key]; return value; } 

    重写 remove(删除) 方法:

    • 删除操作就简单了,;
     remove(key) { const data = this.source, value = data[key]; delete data[key]; delete data[`${key}__expires__`]; return value; } 

    优化点:

    • 记得上次有个同学,是这么评论的:「 删除缓存能放到 constructor 里面执行么,放到 get 里面 不取就一直在那是不是不太好?」;
    • 为什么不用for in而是 for ? for in循环遍历对象的属性时,原型链上的所有属性都将被访问,解决方案:使用hasOwnProperty方法过滤或 Object.keys 会返回自身可枚举属性组成的数组;
     class storage { constructor(props) { this.props = props || {} this.source = this.props.source || window.localStorage this.initRun(); } initRun(){ /* * set 存储方法 * @ param {String} key 键 * @ param {String} value 值,存储的值可能是数组 /对象,不能直接存储,需要转换 JSON.stringify * @ param {String} expired 过期时间,以分钟为单位 * @ 由 @IT平头哥联盟-首席填坑官苏南 分享 */ const reg = new RegExp("__expires__"); let data = this.source; let list = Object.keys(data); if(list.length > 0){ list.map((key,v)=>{ if( !reg.test(key )){ let now = Date.now(); let expires = data[`${key}__expires__`]||Date.now+1; if (now >= expires ) { this.remove(key); }; }; return key; }); }; } } 

    总结:

    以上就是今天为大家总结的分享,您 GET 到了吗?小程序、sessionStorage、localStorage,都适用,做些许调整即可哦,希望今天的分享能给您带来些许成长,如果觉得不错,记得关注下方公众号哦,每周为您推最新分享。

    宝剑锋从磨砺出,梅花香自苦寒来,做有温度的攻城狮!,公众号:honeyBadger8

    作者:苏南 - 首席填坑官
    链接: https://blog.csdn.net/weixin_43254766/article/details/83618630
    交流群:912594095、公众号:honeyBadger8
    本文原创,著作权归作者所有。商业转载请联系@IT平头哥联盟获得授权,非商业转载请注明原链接及出处。

    12 replies    2018-11-07 19:10:35 +08:00
    southSu
        1
    southSu  
    OP
       Nov 7, 2018
    清风舞明月,幽梦落花间。
    一梦醒来,恍如隔世,
    两眉间,相思尽染。我是苏南,周三早安,愿您安好!
    cctv1005s927
        2
    cctv1005s927  
       Nov 7, 2018
    平头哥??
    Showfom
        3
    Showfom  
    PRO
       Nov 7, 2018
    看我打球,跟我去食堂,我又是平头,你喜欢我吧?
    @cctv1005s927

    https://i.loli.net/2018/11/07/5be231d7aa680.png
    MuscleOf2016
        4
    MuscleOf2016  
       Nov 7, 2018
    吓得我以为,江苏 苏南 苏北 内斗尼。哈哈。
    des
        5
    des  
       Nov 7, 2018 via Android
    平头哥??
    lancegin
        6
    lancegin  
       Nov 7, 2018 via iPhone
    美凌格
    farseeraliens
        7
    farseeraliens  
       Nov 7, 2018 via iPhone
    请问 set 后一直不 get 就没效果了吗?
    cctv1005s927
        8
    cctv1005s927  
       Nov 7, 2018
    southSu
        9
    southSu  
    OP
       Nov 7, 2018
    @cctv1005s927

    不那么好过的日子里,
    要学会每天给自己找一个开心的理由,
    哪怕只是阳光很暖,电量很满!下午好,感谢支持,我们是几个朋友一起弄的个团队写点博客而已,不马老师的平头哥,欢迎关注哦
    southSu
        10
    southSu  
    OP
       Nov 7, 2018
    @farseeraliens
    每一个人都应该用努力去惊艳时光,
    生活不会亏待任何一个努力的人!-下午好,感谢支持,this.initRun();方法初始化会进行删除过期的数据,set 之后,肯定要 get 才能取到你要东西,localstorage 本身也是如此!
    southSu
        11
    southSu  
    OP
       Nov 7, 2018
    @MuscleOf2016

    最美好的生活方式
    奔跑在理想的路上,
    回头有一路的故事,
    低头有坚定的脚步,
    抬头有清晰的远方!下午好,不是哦,只是一个名字而已
    Showfom
        12
    Showfom  
    PRO
       Nov 7, 2018
    @cctv1005s927 平头哥的来历啊
    About     Help     Advertise     Blog     API     FAQ     Solana     1011 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 72ms UTC 22:36 PVG 06:36 LAX 15:36 JFK 18:36
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86