业务场景,对已有项目中浏览器本地存储做改造,不同的渠道(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中的缓存读写;