前言
localStorage是我们前端开发人员使用频率较高的api,它允许开发者以键值对的形式在本地永久性地存储数据在游览器,容量比cookie大很多多倍
通常用来缓存各种全局数据,但又因为不会像cookie一样产生时效性,在存储一些需要时效性的数据时需要我们手动清除,颇为麻烦
如何能让永久缓存localStorage能像cookie一样支持设置过期时间呢?
下面写出我的两种方案
localStorage重写
重写localStorage方法代替原生的使用方法,写入utils/localstorage.js中,使用的使用引入使用新的方法缓存数据,分别按如下步骤
1、存储数据时,存入过期时间戳expire
/**
* @param {string} key 存储的键名
* @param {*} value 存储的值
* @param {number} expire 存储天数,未传入视为永久存储
* @description 设置本地存储方法
*/
export function setLocal(key, value, exdays) {
const expire = exdays ? exdays * 24 * 60 * 60 * 1000 : 0 // 天数时间
const storageData = {
key,
value,
expire: exdays ? Date.now() + expire : null, // 当前时间 + 存储时限 = 到期时间戳
};
window.localStorage.setItem(key, JSON.stringify(storageData));
}
2、在获取数据时检查是否过期,已过期就删除
/**
* @param {string} key 存储的键名
* @description 获取本地存储方法
*/
export function getLocal(key) {
try {
const localStorageItem = JSON.parse(window.localStorage.getItem(key));
if (!localStorageItem || !localStorageItem.key) return null // 只对有key值类型的缓存操作
if (!localStorageItem.expire || localStorageItem.expire >= Date.now()) {
// 无过期时间或者在有效期内返回数据
return localStorageItem.value;
}
// 验证失败或者已过期返回null并删除相应的缓存
removeLocalItem(key);
return null
} catch (error) {
console.log("无法解析的 JSON 字符串: " + error.message);
}
}
/**
* 删除单个本地存储方法
* @param {string} key 存储的键名
*/
export function removeLocalItem(key) {
window.localStorage.removeItem(key);
}
3、定期或是在恰当的时机检查缓存
虽然在获取缓存数据时增加了过期时间判断,但是本质上仍然不会过期后自动删除,只是模拟了过期时间的方法,并非完全具备自动过期的能力
我们需要在适当的时机手动清理过期的数据,例如在 页面加载时检查过期数据并进行清理
/**
* @description 检查删除本地存储所有已过期数据
*/
export function checkLocal() {
const storageKeys = Object.keys(window.localStorage);
// 获取所有的localStorage循环
storageKeys.forEach((item) => {
getLocal(item) // 获取数据方法,过期后会调用删除方法
});
}
例如在vue的入口文件 main.js
引入该方法
import Vue from 'vue'
import App from './App.vue'
import { checkLocal } from './utils/localstorage.js'
Vue.config.productionTip = false
checkLocal() // 检查本地缓存是否过期
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
或者在路由加载切换时,接口请求时,定时任务都可以调用方法检查本地缓存是否过期
cookie
1、使用cookie存储key值,localStorage存储value值
重写存储方法,通过cookie的特性支持设置过期时间,对要缓存的数据分别存放在cookie和localStorage中
/**
* @param {String} key 键名
* @param {*} value 键值
* @param {Number} exdays 天数,默认7天
* @description 设置cookie值
*/
export function setCookie(key, value, exdays = 7) {
var currentTime = new Date();
currentTime.setTime(currentTime.getTime()+(exdays * 24 * 60 * 60 * 1000)); // 当前时间+传入天数=到期时间
var expires = "expires="+ currentTime.toGMTString(); // 将日期转换为 GMT 格式的字符串
document.cookie = `${key}=${key}; ${expires}`; // 存入cookie
localStorage.setItem(key, JSON.stringify(value)) // 存入缓存
}
2、获取时根据cookie存储的key获取localStorage的值,已过期不存在就删除
取值时获取cookie存储的键名,如果不存在则意味着缓存过期,返回空并删除localStorage内缓存
/**
* @param {String} key 键名
* @description 获取单个cookie值
*/
export function getCookie(key) {
const name = `${key}=`;
const cookieList = document.cookie.split(';'); // 获取所有cookie
const index = cookieList.findIndex(item => {
const current = item.trim(); // 去除字符串两端空白避免indexOf查找位置不准确
return current.indexOf(name) == 0 // 在字符串第一位找到
})
console.log(index, 'idnex')
if (index !== -1) {
// cookie中找到改key值,从localStorage缓存获取值
return JSON.parse(localStorage.getItem(key) || '')
} else {
// 未找到表明已过期或不存在,删除localStorage缓存中该值,返回空
removeCookie(key)
return ''
}
}
/**
* @param {String} key 键名
* @description 删除单个cookie值
*/
export function removeCookie(cookieName) {
// 删除cookie只需把时间设置位以前的时间即可删除
document.cookie = `${cookieName}=; expires=Thu, 01 Jan 1970 00:00:00 GMT;`;
localStorage.removeItem(cookieName)
}
结尾
再在给 localStorage 存入值时还可以进行加密,这里不做展示
以上便是总结的方法,如有不足之处请指出,感谢!