前端中级篇之给localStorage和sessionStorage设置失效时间
1 前言
BOM提供了localStorage和sessionStorage用于在浏览器中保存页面数据,区别在于:使用localStorage存储的数据将会一一直存在(除非使用removeItem或者清除缓存),而sessionStorage的有效期是和存储数据脚本所在的最顶层的窗口或者是浏览器标签是一样的,一旦窗口或者标签页被永久关闭了,存储的数据也就失效了。并且,这两种web存储方式都不支持设置过期时间,那如果业务中有需求需要设置过期时间,应该怎么做呢?这个时候就需要我们自己封装一下localStorage和sessionStorage。
2 封装localStorage和sessionStorage
业务需求:如果网页需要频繁请求同一个接口,而该接口返回的数据的更新频率又很低,这种时候我认为最好的做法就是使用sessionStorage,在第一次打开该页面的时候请求一次数据然后把数据存储到sessionStorage中,后续就可以直接在本地读取数据了避免频繁发送请求。但是我又希望能够隔一段时间让本地的sessionStorage失效,继而发送一个请求,以更新本地存储。
我给出的方案:封装sessionStorage,给其中的数据设置一个过期时间,每次请求数据的时候先根据预设的key访问sessionStorage,如果其中存有数据,比较数据是否过期,如果没有过期就直接使用sessionStorage中的数据;如果数据过期了,通过接口请求数据,并且把返回的数据保存到sessionStorage。
直接看封装好的webStorage代码,注释写的比较详细,就不再过多解释了。
const webStorage = {
/**
* 从storage中读取数据,使用与sessionStorage和localStorage相同的读取数据函数名称
* @param {*} storageType 存储类型,只能为sessionStorage或localStorage
* @param {*} key 读取数据的key
* @returns
*/
getItem(storageType, key) {
// 如果storageType字段不合法,直接返回空
if (!['sessionStorage', 'localStorage'].includes(storageType)) {
return null;
}
const storeData = window[storageType].getItem(key);
// 如果根据key没有找到数据,直接返回空
if (!storeData) {
return null;
}
const parsedData = JSON.parse(storeData);
const currentTimestamp = new Date().getTime();
// 将当前的时间戳和保存在storage中的timestamp进行比较
// 如果时间差小于等于过期时间说明没有过期,直接返回数据
// 否则,说明数据已经过期,将storage中的key清除
if (currentTimestamp - parsedData.timestamp <= parsedData.expire) {
return parsedData.value;
} else {
window[storageType].removeItem(key);
}
return null;
},
/**
* 向storage中添加字段,使用与sessionStorage和localStorage相同的读取数据函数名称
* @param {*} storageType 存储类型,只能为sessionStorage或localStorage
* @param {*} key 保存数据的key
* @param {*} value 保存的数据
* @param {*} expire 过期时间,默认为1分钟
*/
setItem(storageType, key, value, expire = 60000) {
// 如果storageType字段不合法,直接返回空
if (!['sessionStorage', 'localStorage'].includes(storageType)) {
return;
}
const obj = {
value: value,
expire: expire,
timestamp: new Date().getTime()
}
const stringfiedData = JSON.stringify(obj);
window[storageType].setItem(key, stringfiedData);
}
}