需求场景:从A系统登录跳转到B系统,这个时候B系统不需要再重新登录。
实现方案:因为不需要后端处理,前端实现是否登录的判断,故选择使用h5的postMessage API,在A系统跳转时给B系统发送消息。
实现代码:
A系统
window.sender = window.open(url) // url:B系统的地址
const timer = setInterval(function () {
window.sender.postMessage(str), url) // str:发送给B系统的参数
}, 200)
window.addEventListener('message', function (event) {
if (event.data === 'success') {
clearInterval(timer)
}
}, false)
B系统
window.onmessage = function(e) {
const isProduction = process.env.NODE_ENV === 'production'
let flag = isProduction ? config.mainEntry.origin.includes(e.origin) : true
// 本地调试
if (e.origin.includes('localhost')) flag = true
if (flag && e.data) {
if (e.data.constructor !== String) return
const data = JSON.parse(e.data)
e.source.postMessage('success', e.origin)
window.location.href = window.location.origin + window.location.pathname
window.open(window.location.href, '_self')
}
}
注意事项:
- 使用定时器的原因:B系统只要在加载完成以后才能收到A系统发送的消息,故需要不断的给B发消息,同时为了清除定时器,在B接收到消息后也需要给A发送一个回执消息,告知A已收到数据。
- 从A跳转到B时,最好在url上添加一些额外信息,比如:
url?from=a
,这么做是因为在B系统加载完成后需要走前端路由进行跳转,这个时候如果B还没有收到A发送的消息,那么这个跳转必须阻塞,直到接收到A的消息,然而我们可以通过url
上的from
参数来做判断。这也是为什么在B接收到消息以后要使用window.open
重新加载一次原始url
的原因。
- 从A跳转到B时,最好在url上添加一些额外信息,比如:
网友评论