对已有项目中的浏览器本地存储(localStorage、sessionStorage)实现(分渠道、系统)数据隔离

业务场景,对已有项目中浏览器本地存储做改造,不同的渠道(appid)加以区分。如果手动更改每个文件的localStorage或者sessionStorage等调用方法,工作量非常大且易出错,经过自己的思考和优化之后,实现了如下方案:

import { getQueryVariable } from '@/utils'

/**
 * @type {{"29": 普康宝}}
 */
const appsEnum = {
    29: 'pkb'
}
const appId = localStorage.getItem('appId') || getQueryVariable('appid') || getQueryVariable('appId') || ''
const prefix = appsEnum[appId]
localStorage.setItem('appId', appId) // appid
localStorage.setItem('appMark', prefix) // app缓存隔离标记

/**
 * 排除三方key值,高德、vConsole、听云
 */
const isCustomKey = (key) => {
    return !/^_AMap_/.test(key) && !/^vConsole/.test(key) && !/^TY_/.test(key)
}

export const initStorageMethods = () => {
    console.log('执行initStorageMethods')
    const oldSetItemLocal = localStorage.setItem.bind(localStorage)
    const oldGetItemLocal = localStorage.getItem.bind(localStorage)
    const oldSetItemSession = sessionStorage.setItem.bind(sessionStorage)
    const oldGetItemSession = sessionStorage.getItem.bind(sessionStorage)

    localStorage.__proto__.oldSetItemLocal = oldSetItemLocal
    localStorage.__proto__.oldGetItemLocal = oldGetItemLocal
    sessionStorage.__proto__.oldSetItemSession = oldSetItemSession
    sessionStorage.__proto__.oldGetItemSession = oldGetItemSession

    localStorage.setItem = function(key, value) {
        if(prefix && isCustomKey(key)) {
            const localData = JSON.parse(oldGetItemLocal(prefix) || '{}')
            localData[key] = value
            oldSetItemLocal(prefix, JSON.stringify(localData))
        } else {
            oldSetItemLocal(key, value)
        }
    }
    localStorage.getItem = function(key) {
        if(prefix && isCustomKey(key)) {
            const localData = JSON.parse(oldGetItemLocal(prefix) || '{}')
            return localData[key]
        } else {
            return oldGetItemLocal(key)
        }
    }
    localStorage.removeItem = function(key) {
        return localStorage.setItem(key, undefined)
    }
    sessionStorage.setItem = function(key, value) {
        if(prefix && isCustomKey(key)) {
            const sessionData = JSON.parse(oldGetItemSession(prefix) || '{}')
            sessionData[key] = value
            oldSetItemSession(prefix, JSON.stringify(sessionData))
        } else {
            oldSetItemSession(key, value)
        }
    }
    sessionStorage.getItem = function(key) {
        if(prefix && isCustomKey(key)) {
            const sessionData = JSON.parse(oldGetItemSession(prefix) || '{}')
            return sessionData[key]
        } else {
            return oldGetItemSession(key)
        }
    }
    sessionStorage.removeItem = function(key) {
        return sessionStorage.setItem(key, undefined)
    }
}

项目中存取的使用无需改变:


使用方法

实现效果:
1.对localStorage和sessionStorage通过渠道和appMark标记隔离;
2.在隔离的过程中不影响三方引入的sdk中的缓存读写;


自定义隔离的缓存数据

你可能感兴趣的:(对已有项目中的浏览器本地存储(localStorage、sessionStorage)实现(分渠道、系统)数据隔离)