localStorage 设置过期时间删除的方案总结大全

600 阅读3分钟

前言

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的特性支持设置过期时间,对要缓存的数据分别存放在cookielocalStorage

/**
 * @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 存入值时还可以进行加密,这里不做展示

以上便是总结的方法,如有不足之处请指出,感谢!