Web本地缓存的正确使用

最终答案:

1.将缓存localStorage、sessionStorage放在VueX中统一进行维护

2.要对本地缓存做时效处理

3.要对缓存做加密处理

4.根据版本生成缓存键

export const LOCALE_KEY = 'LOCALE__';
// 生成缓存配置,主要包含过期时间、是否加密、根据版本生成缓存键
const createOption = createOptions(localStorage,{TimeOut:24*60*60*7})
const ls = createStorage(createOption);
const lsLocaleSetting = ls.get(LOCALE_KEY) || localeSetting;

export const useLocaleStore = define({
    id: 'app-locale',
    state: (): LocaleState => ({
        // 缓存信息
        localInfo: lsLocaleSetting,
    }),
    getters:{},
    actions:{
        // 同步修改本地、VueX的缓存信息
        setLocaleInfo(info) {
             this.localInfo = { ...this.localInfo, ...info };
             ls.set(LOCALE_KEY, this.localInfo);
        },
        // 初始化VueX、本地的缓存信息,这里主要是国际化配置
        initLocale() {
          this.setLocaleInfo({
            ...localeSetting,
            ...this.localInfo,
          });
        },
    }
})

export const localeSetting = {
  showPicker: true,
  // 地点
  locale: LOCALE.ZH_CN,
  // 默认语言
  fallback: LOCALE.ZH_CN,
  // 可用地区
  availableLocales: [LOCALE.ZH_CN, LOCALE.EN_US],
};
export const LOCALE = {
  ZH_CN: 'zh_CN',
  EN_US: 'en',
};
const createOptions = (storage: Storage, options: Options = {}): Options => {
  return {
    // 开发模式不加密
    hasEncrypt: enableStorageEncryption,
    storage,
    // 根据版本生成缓存键
    prefixKey: getStorageShortName(),
    ...options,
  };
};

// 根据当前开发所处的环境判断是否使用aes加密系统缓存
export const enableStorageEncryption = !isDevMode();
// 判断是否处于开发环境
export function isDevMode(): boolean {
  return import.meta.env.DEV;
}

// 根据版本生成缓存键,格式为:项目名__所处环境__版本号__
export function getStorageShortName() {
  return `${getCommonStoragePrefix()}${`__${pkg.version}`}__`.toUpperCase();
}

export function getCommonStoragePrefix() {
  // 从环境中获取项目名
  const { VITE_GLOB_APP_SHORT_NAME } = import.meta.env;
  // 获取当前环境是开发还是生产并记录
  return `${VITE_GLOB_APP_SHORT_NAME}__${import.meta.env.MODE}`.toUpperCase();
}


// key和iv是Aes加密所需的自定义密钥
export const createStorage({
  storage = sessionStorage,
  key = cacheCipher.key,
  iv = cacheCipher.iv,
  timeout = null,
  hasEncrypt = true,
  prefixKey = ''
}: Partial<CreateStorageParams> = {}) => {
  // 判断密钥格式是否正确
  if (hasEncrypt && [key.length, iv.length].some((item) => item !== 16)) {
    throw new Error('When hasEncrypt is true, the key or iv must be 16 bits!');
  }
  // 创建Aes加密工具
  const encryption = new AesEncryption({ key, iv });

  // 构造本地缓存实体类
  const WebStorage = class WebStorage {
    private storage: Storage;
    private prefixKey?: string;
    private encryption: AesEncryption;
    private hasEncrypt: boolean;
    

    constructor() {
      this.storage = storage;
      this.prefixKey = prefixKey;
      this.encryption = encryption;
      this.hasEncrypt = hasEncrypt;
    }
    
    //prefixKey格式为:项目名__所处环境__版本号__
    private getKey(key: string) {
      return `${this.prefixKey}${key}`.toUpperCase();
    }

    // key是缓存键,value是值,expire是过期时间(秒)
    set(key: string, value: any, expire: number | null = timeout) {
      const stringData = JSON.stringify({
        value,
        time: Date.now(),
        expire: !expire ? new Date().getTime() + expire * 1000 : null,
      });
      // 是否加密value
      const stringifyValue = this.hasEncrypt
        ? this.encryption.encryptByAES(stringData)
        : stringData;
      // 设置缓存
      this.storage.setItem(this.getKey(key), stringifyValue);
    }

    
    get(key: string, def: any = null): any {
      const val = this.storage.getItem(this.getKey(key));
      if (!val) return def;

      try {
        // 是否需要解密
        const decVal = this.hasEncrypt ? this.encryption.decryptByAES(val) : val;
        const data = JSON.parse(decVal);
        const { value, expire } = data;
        // 判断是否过期
        if (isNullOrUnDef(expire) || expire >= new Date().getTime()) {
          return value;
        }
        // 过期则移除
        this.remove(key);
      } catch (e) {
        return def;
      }
    }

    
    remove(key: string) {
      this.storage.removeItem(this.getKey(key));
    }

   
    clear(): void {
      this.storage.clear();
    }
  };
  return new WebStorage();
};

猜你喜欢

转载自blog.csdn.net/liushihao_/article/details/139238964