给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 相关文章推荐
使用ExtJS技术实现的拖动树结点
Aug 05 Javascript
jquery判断字符输入个数(数字英文长度记为1,中文记为2,超过长度自动截取)
Oct 15 Javascript
JavaScript中的this使用详解
Jul 27 Javascript
学习JavaScript图片预加载模块
Nov 07 Javascript
JavaScript中捕获/阻止捕获、冒泡/阻止冒泡方法
Dec 07 Javascript
Bootstrap表单控件学习使用
Mar 07 Javascript
Vue filters过滤器的使用方法
Jul 14 Javascript
vue多页面开发和打包正确处理方法
Apr 20 Javascript
arctext.js实现文字平滑弯曲弧形效果的插件
May 13 Javascript
JavaScript+HTML5 canvas实现放大镜效果完整示例
May 15 Javascript
js验证密码强度解析
Mar 18 Javascript
js实现小球在页面规定的区域运动
Jun 16 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(8) php 数组
2010/03/05 PHP
PHP获取文件的MD5值并判断是否被修改的例子
2014/06/19 PHP
ThinkPHP3.1的Widget新用法
2014/06/19 PHP
yii操作session实例简介
2014/07/31 PHP
PHP实现无限极分类图文教程
2014/11/25 PHP
php实现字符串首字母大写和单词首字母大写的方法
2015/03/14 PHP
php简单判断文本编码的方法
2015/07/30 PHP
php语言的7种基本的排序方法
2020/12/28 PHP
PHP那些琐碎的知识点(整理)
2017/05/20 PHP
ThinkPHP实现登录退出功能
2017/06/29 PHP
javascript 文档的编码问题解决
2009/03/01 Javascript
jquery获取ASP.NET服务器端控件dropdownlist和radiobuttonlist生成客户端HTML标签后的value和text值
2010/06/28 Javascript
如何在一个页面显示多个百度地图
2013/04/07 Javascript
网站如何做到完全不需要jQuery也可以满足简单需求
2013/06/27 Javascript
jquery select多选框的左右移动 具体实现代码
2013/07/03 Javascript
jQuery 设置 CSS 属性示例介绍
2014/01/16 Javascript
JS基于FileSystemObject创建一个指定路径的TXT文本文件
2015/08/05 Javascript
JavaScript淡入淡出渐变简单实例
2015/08/06 Javascript
简单实现jQuery多选框功能
2017/01/09 Javascript
Vue resource三种请求格式和万能测试地址
2018/09/26 Javascript
iview实现select tree树形下拉框的示例代码
2018/12/21 Javascript
vue路由缓存的几种实现方式小结
2020/02/02 Javascript
[01:01:35]Optic vs paiN 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
浅谈python 里面的单下划线与双下划线的区别
2017/12/01 Python
Python构建网页爬虫原理分析
2017/12/19 Python
python如何爬取个性签名
2018/06/19 Python
Python制作exe文件简单流程
2019/01/24 Python
python之当你发现QTimer不能用时的解决方法
2019/06/21 Python
python梯度下降算法的实现
2020/02/24 Python
在 Pycharm 安装使用black的方法详解
2020/04/02 Python
HTML5页面无缝闪开的问题及解决方案
2020/06/11 HTML / CSS
印尼穆斯林时尚购物网站:Hijabenka
2016/12/10 全球购物
美国爆米花工厂:The Popcorn Factory
2019/09/14 全球购物
环保建议书500字
2014/05/14 职场文书
导游词之永泰公主墓
2019/12/04 职场文书
Java 超详细讲解hashCode方法
2022/04/07 Java/Android