wujie
wujie copied to clipboard
主应用跟子应用都用了localStorage 来记录登录的信息 同个浏览器2个标签页打开主应用 跟子应用 会被覆盖
描述bug 主应用跟子应用都用了localStorage 来记录登录的信息 同个浏览器2个标签页打开主应用 跟子应用 会被覆盖
如何复现 主应用跟子应用都用了localStorage 来记录登录的信息 同个浏览器2个标签页打开主应用 跟子应用 会被覆盖
错误截图
最小复现仓库或者地址
wujie暂不支持,分享下我的解决方案,在主应用中修改window的localStorage事件,来给localStorage根据url设置前缀,子应用用的也是主应用的window,所以子应用不用处理
// 隔离localstorage
const originalSetItem = window.localStorage.setItem;
const originalGetItem = window.localStorage.getItem;
// 不需要添加前缀的白名单存储键
const whiteStorage = ['core_platform_user_information'];
window.localStorage.setItem = function (key, value) {
originalSetItem.call(
window.localStorage,
// 这里加上的localStorage前缀根据自己需求修改
whiteStorage.includes(key) ? key : window.location.pathname + '_' + key,
value
);
};
window.localStorage.getItem = function (key) {
return originalGetItem.call(
window.localStorage,
whiteStorage.includes(key) ? key : window.location.pathname + '_' + key
);
};
window.localStorage.clear = function () {
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (
key.startsWith(window.location.pathname) ||
whiteStorage.includes(key)
) {
localStorage.removeItem(key);
}
}
};
wujie暂不支持,分享下我的解决方案,在主应用中修改window的localStorage事件,来给localStorage根据url设置前缀,子应用用的也是主应用的window,所以子应用不用处理
// 隔离localstorage const originalSetItem = window.localStorage.setItem; const originalGetItem = window.localStorage.getItem; // 不需要添加前缀的白名单存储键 const whiteStorage = ['core_platform_user_information']; window.localStorage.setItem = function (key, value) { originalSetItem.call( window.localStorage, // 这里加上的localStorage前缀根据自己需求修改 whiteStorage.includes(key) ? key : window.location.pathname + '_' + key, value ); }; window.localStorage.getItem = function (key) { return originalGetItem.call( window.localStorage, whiteStorage.includes(key) ? key : window.location.pathname + '_' + key ); }; window.localStorage.clear = function () { for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); if ( key.startsWith(window.location.pathname) || whiteStorage.includes(key) ) { localStorage.removeItem(key); } } };
主应用上加了这段代码,子应用在调用 setItem 和 getItem 并没有触发主应用的这段代码吗。看代码应该是没有问题的,不知道是不是我那些写得不对。可以麻烦大佬贴个demo吗? 感谢感谢
主应用上加了这段代码,子应用在调用 setItem 和 getItem 并没有触发主应用的这段代码吗。看代码应该是没有问题的,不知道是不是我那些写得不对。可以麻烦大佬贴个demo吗? 感谢感谢
不好意思,可能是我当时弄错了,这样写子应用确实不生效,通过设置plugins给子应用插入该段代码
<template>
<WujieVue
height="100%"
name="vue2"
:url="wujieUrl"
:plugins="plugins"
:props="{}"></WujieVue>
</template>
<script>
export default {
data() {
return {
wujieUrl: window.wujieUrl,
plugins: [
{
// 在子应用所有的js之前
jsBeforeLoaders: [
// 插入一个内联脚本,隔离localstorage
{
content: `const originalSetItem = window.localStorage.setItem;
const originalGetItem = window.localStorage.getItem;
const whiteStorage = ['core_platform_user_information'];
window.localStorage.setItem = function (key, value) {
originalSetItem.call(
window.localStorage,
whiteStorage.includes(key) ? key : window.location.pathname + '_' + key,
value
);
};
window.localStorage.getItem = function (key) {
return originalGetItem.call(
window.localStorage,
whiteStorage.includes(key) ? key : window.location.pathname + '_' + key
);
};
window.localStorage.clear = function () {
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (
key.startsWith(window.location.pathname) ||
whiteStorage.includes(key)
) {
localStorage.removeItem(key);
}
}
};`,
},
],
},
{
// 解决子应用使用vite时样式丢失问题
patchElementHook(element, iframeWindow) {
if (element.nodeName === 'STYLE') {
element.insertAdjacentElement = function (_position, ele) {
iframeWindow.document.head.appendChild(ele);
};
}
},
},
{
// 在子应用所有的css之前,为子应用插入样式
cssBeforeLoaders: [
// 强制使子应用body定位是relative
{ content: 'body{position: relative !important}' },
{ content: 'html{height: 100%}' },
{ content: 'body{height: 100%}' },
{ content: '#app{height: 100%}' },
],
},
{
// 解决子应用计算偏移量错误问题
jsLoader: (code) => {
// 替换popper.js内计算偏左侧偏移量
var codes = code.replace(
'left: elementRect.left - parentRect.left',
'left: fixed ? elementRect.left : elementRect.left - parentRect.left'
);
// 替换popper.js内右侧偏移量
return codes.replace(
'popper.right > data.boundaries.right',
'false'
);
},
},
],
};
},
};
</script>