给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 相关文章推荐
js验证表单大全
Nov 25 Javascript
Javascript 跨域访问解决方案
Feb 14 Javascript
基于jQuery实现左右div自适应高度完全相同的代码
Aug 09 Javascript
jquery通过select列表选择框对表格数据进行过滤示例
May 07 Javascript
JavaScript作用域链示例分享
May 27 Javascript
jQuery选择器源码解读(七):elementMatcher函数
Mar 31 Javascript
Bootstrap基本插件学习笔记之Popover提示框(19)
Dec 08 Javascript
Angular4学习笔记之新建项目的方法
Jul 18 Javascript
详解Angular5 服务端渲染实战
Jan 04 Javascript
layui实现下拉框三级联动
Jul 26 Javascript
JavaScript中this函数使用实例解析
Feb 21 Javascript
详解Vue数据驱动原理
Nov 17 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校验表单检测字段是否为空的方法
2015/03/20 PHP
在Mac OS的PHP环境下安装配置MemCache的全过程解析
2016/02/15 PHP
老生常谈PHP位运算的用途
2017/03/12 PHP
PHP5.0 TIDY_PARSE_FILE缓冲区溢出漏洞的解决方案
2018/10/14 PHP
js对象的构造和继承实现代码
2010/12/05 Javascript
使用js判断数组中是否包含某一元素(类似于php中的in_array())
2013/12/12 Javascript
一个网页标题title的闪动提示效果实现思路
2014/03/22 Javascript
jquery 自定义容器下雨效果可将下雨图标改为其他
2014/04/23 Javascript
JavaScript的Number对象的toString()方法
2015/12/18 Javascript
chrome浏览器如何断点调试异步加载的JS
2016/09/05 Javascript
微信小程序商城项目之商品属性分类(4)
2017/04/17 Javascript
JS/jquery实现一个网页内同时调用多个倒计时的方法
2017/04/27 jQuery
JavaScript变量作用域_动力节点Java学院整理
2017/06/27 Javascript
老生常谈js中的MVC
2017/07/25 Javascript
谈谈vue中mixin的一点理解
2017/12/12 Javascript
浅谈手写node可读流之流动模式
2018/06/01 Javascript
Koa代理Http请求的示例代码
2018/10/10 Javascript
仿ElementUI实现一个Form表单的实现代码
2019/04/23 Javascript
layui 选择列表,打勾,点击确定返回数据的例子
2019/09/02 Javascript
Vue父子传递实例讲解
2020/02/14 Javascript
vue-cli中实现响应式布局的方法
2021/03/02 Vue.js
[02:05]2014DOTA2国际邀请赛 BBC外卡赛赛后总结
2014/07/09 DOTA
[02:32]DOTA2亚洲邀请赛 C9战队出场宣传片
2015/02/07 DOTA
Python的设计模式编程入门指南
2015/04/02 Python
Python实时获取cmd的输出
2015/12/13 Python
Python字符串内置函数功能与用法总结
2019/04/16 Python
pybind11和numpy进行交互的方法
2019/07/04 Python
Python3 中作为一等对象的函数解析
2019/12/11 Python
Python urllib request模块发送请求实现过程解析
2020/12/10 Python
CSS3属性使网站设计增强同时不消弱可用性
2009/08/29 HTML / CSS
萌新HTML5 入门指南(二)
2020/11/09 HTML / CSS
英国最大的电子产品和家电零售企业:Currys PC World
2016/09/24 全球购物
赵乐秦在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
优秀班主任申报材料
2014/12/16 职场文书
网络销售员岗位职责
2015/04/11 职场文书
100句人生哲理语录集锦:强者征服今天,懒汉坐等明天
2019/10/18 职场文书