需求場(chǎng)景:從A系統(tǒng)登錄跳轉(zhuǎn)到B系統(tǒng)掸掸,這個(gè)時(shí)候B系統(tǒng)不需要再重新登錄潮剪。
實(shí)現(xiàn)方案:因?yàn)椴恍枰蠖颂幚砟寤荩岸藢?shí)現(xiàn)是否登錄的判斷,故選擇使用h5的postMessage API侈沪,在A系統(tǒng)跳轉(zhuǎn)時(shí)給B系統(tǒng)發(fā)送消息揭璃。
實(shí)現(xiàn)代碼:
A系統(tǒng)
window.sender = window.open(url) // url:B系統(tǒng)的地址
const timer = setInterval(function () {
window.sender.postMessage(str), url) // str:發(fā)送給B系統(tǒng)的參數(shù)
}, 200)
window.addEventListener('message', function (event) {
if (event.data === 'success') {
clearInterval(timer)
}
}, false)
B系統(tǒng)
window.onmessage = function(e) {
const isProduction = process.env.NODE_ENV === 'production'
let flag = isProduction ? config.mainEntry.origin.includes(e.origin) : true
// 本地調(diào)試
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')
}
}
注意事項(xiàng):
- 使用定時(shí)器的原因:B系統(tǒng)只要在加載完成以后才能收到A系統(tǒng)發(fā)送的消息,故需要不斷的給B發(fā)消息峭竣,同時(shí)為了清除定時(shí)器塘辅,在B接收到消息后也需要給A發(fā)送一個(gè)回執(zhí)消息,告知A已收到數(shù)據(jù)皆撩。
- 從A跳轉(zhuǎn)到B時(shí)扣墩,最好在url上添加一些額外信息,比如:
url?from=a
扛吞,這么做是因?yàn)樵贐系統(tǒng)加載完成后需要走前端路由進(jìn)行跳轉(zhuǎn)呻惕,這個(gè)時(shí)候如果B還沒(méi)有收到A發(fā)送的消息,那么這個(gè)跳轉(zhuǎn)必須阻塞滥比,直到接收到A的消息亚脆,然而我們可以通過(guò)url
上的from
參數(shù)來(lái)做判斷。這也是為什么在B接收到消息以后要使用window.open
重新加載一次原始url
的原因盲泛。
- 從A跳轉(zhuǎn)到B時(shí)扣墩,最好在url上添加一些額外信息,比如: