给localStorage设置一个过期时间的方法分享


Posted in Javascript onNovember 06, 2018

思考点

在 web 开发中,我们知道 cookie、session、localStorage都可以保存用户的数据,cookie的 domain、path 限制了 cookie 的跨域, 有数量和大小的限制,可以设置有效时间。 session是后台在浏览器注入一个设置了 httponly 的不可读取的 cookie , session data由后台保存在数据库或者内存中,在web中,session 是靠 cookie 作为唯一标示来实现的,也可以设置过期时间。 localStorage 是 H5 的数据存储办法, 也是有大小限制的,但是不可以设置过期时间。

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

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

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

实现思路

抱歉,黑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;
 });
 };
 }
}

总结:

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
任意位置显示html菜单
Feb 01 Javascript
Prototype源码浅析 String部分(二)
Jan 16 Javascript
解析瀑布流布局:JS+绝对定位的实现
May 08 Javascript
javascript 通用loading动画效果实例代码
Jan 14 Javascript
jquery提交form表单时禁止重复提交的方法
Feb 13 Javascript
js动态生成Html元素实现Post操作(createElement)
Sep 14 Javascript
详解Vue方法与事件
Mar 09 Javascript
微信小程序按钮去除边框线分享页面功能
Aug 27 Javascript
jQuery+PHP实现上传裁剪图片
Jun 29 jQuery
JS数组去重的6种方法完整实例
Dec 08 Javascript
jQuery实现弹出层效果
Dec 10 jQuery
JavaScript继承的三种方法实例
May 12 Javascript
移动端H5页面返回并刷新页面(BFcache)的方法
Nov 06 #Javascript
学习使用ExpressJS 4.0中的新Router的用法
Nov 06 #Javascript
vue项目上传Github预览的实现示例
Nov 06 #Javascript
React Component存在的几种形式详解
Nov 06 #Javascript
支付宝小程序tabbar底部导航
Nov 06 #Javascript
利用JavaScript缓存远程窃取Wi-Fi密码的思路详解
Nov 05 #Javascript
利用hasOwnProperty给数组去重的面试题分享
Nov 05 #Javascript
You might like
PHP编程基本语法快速入门手册
2016/01/07 PHP
php简单实现多语言切换的方法
2016/05/09 PHP
PHP批量删除jQuery操作
2017/07/23 PHP
Laravel项目中timeAgo字段语言转换的改善方法示例
2019/09/16 PHP
Jquery操作Select 简单方便 一个js插件搞定
2009/11/12 Javascript
jQuery 1.4 15个你应该知道的新特性(译)
2010/01/24 Javascript
jquery $.fn $.fx是什么意思有什么用
2013/11/04 Javascript
jquery 获取dom固定元素 添加样式的简单实例
2014/02/04 Javascript
jQuery实现的一个tab切换效果内部还嵌有切换
2014/08/10 Javascript
JavaScript+html5 canvas绘制缤纷多彩的三角形效果完整实例
2016/01/26 Javascript
JS实现消息来时让网页标题闪动效果的方法
2016/04/20 Javascript
分分钟玩转Vue.js组件(二)
2017/03/01 Javascript
详解PHP后期静态绑定分析与应用
2018/03/21 Javascript
使用 vue-i18n 切换中英文效果
2018/05/23 Javascript
Vue仿微信app页面跳转动画效果
2019/08/21 Javascript
微信小程序仿通讯录功能
2020/04/09 Javascript
Javascript中的奇葩知识,你知道吗?
2021/01/25 Javascript
python 基础教程之Map使用方法
2017/01/17 Python
Python入门之三角函数atan2()函数详解
2017/11/08 Python
python机器学习实战之树回归详解
2017/12/20 Python
Python+树莓派+YOLO打造一款人工智能照相机
2018/01/02 Python
Python读取Json字典写入Excel表格的方法
2018/01/03 Python
python 判断网络连通的实现方法
2018/04/22 Python
python爬虫 execjs安装配置及使用
2019/07/30 Python
使用python实现多维数据降维操作
2020/02/24 Python
利用CSS3的checked伪类实现OL的隐藏显示的方法
2010/12/18 HTML / CSS
美国最大的购物网站:Amazon.com(亚马逊美国)
2020/05/23 全球购物
使用索引有什么好处
2016/07/27 面试题
六查六看剖析材料
2014/10/06 职场文书
个人对照检查剖析材料
2014/10/13 职场文书
2014年电信员工工作总结
2014/12/19 职场文书
简历中自我评价范文
2015/03/11 职场文书
社区干部培训心得体会
2016/01/06 职场文书
简单且有用的Python数据分析和机器学习代码
2021/07/02 Python
ant design charts 获取后端接口数据展示
2022/05/25 Javascript
详解ZABBIX监控ESXI主机的问题
2022/06/21 Servers