需求背景:
存在多個項目(頂級域名相同.scc.com),當打開多個tab頁時,我在一個頁面退出登錄,其他頁面同步信息,頁面彈出已登出提示。
實現方式 iframe + postMessage + localStorage
如有三個已登陸的頁面 A1 A2 B1
頁面A1: http://a1.scc.com
頁面A2: http://a2.scc.com
頁面B1: http://b1.scc.com
一個空的iframe頁面: http://static.scc.com/iframe.html
http://static.scc.com/iframe.html 內容如下
<html>
<body>
<script>
window.addEventListener("storage", function (ev) {
ev = window.event || ev
if (ev.key == "scc_message") {
window.parent.postMessage(ev.newValue, "*");
}
});
function postMessageToStorage(message) {
localStorage.setItem("scc_message", JSON.stringify(message));
localStorage.removeItem("scc_message");
}
window.addEventListener("scc_message", function (ev) {
ev = window.event || ev
let data = ev.data;
postMessageToStorage(data);
});
</script>
</body>
</html>
頁面 A1 A2 B1 代碼相同
DOM引入iframe標簽
<iframe id="sccproxy" src="//static.scc.com/iframe.html" style="width:0px;height:0px;frameBorder:0"></iframe>
<div v-if=flag">
<h3><i></i><span >登錄狀態已改變</span></h3>
<p>當前賬號的登錄狀態已改變,頁面即將刷新。</p>
<div><a href="/">確定</a></div>
</div>
<button @click="sendMessageToTab({type:''sccExit})">退出登錄<button>
js代碼
data () {
return {
flag:false
}
}
mounted () {
this.addMessageListener ()
},
methods: {
addMessageListener () {
let _this = this
window.addEventListener("message", function (ev) {
ev = window.event || ev
let data = ev.data;
let source = ev.source;
let origin = ev.origin;
if (!data) return;
if (origin.indexOf("//static.scc.com") >= 0) {
try {
let info = JSON.parse(JSON.parse(data));
if (info.type == "sccExit" && !document.hasFocus()) {
_this.flag = true
}
} catch (e) {
console.log(e)
}
}
});
},
sendMessageToTab (data) {
try {
document.querySelector("#sccproxy").contentWindow.postMessage(JSON.stringify(data), 'http://static.scc.com');
} catch (err) {
console.log(err)
}
}
}
