前言
最近有一个需求是从当前项目带着token和uuid点击按钮跳转到另一个不同域名的项目去,在纠结了多个跨域通信的方法后,最后选择较简单的postMessage来进行通信
PostMessage
介绍:通常只有符合同源策略的两个页面才能相互通信,()方法提供了一种受控机制来规避此限制,就能安全的实现跨源通信
语法
(message, targetOrigin, [transfer])
参数介绍
otherWindow:其它窗口的引用,比如iframe的contentWindow属性,执行返回的窗口对象,打开过页面获取到的,或者是命名过或数值索引的
message:将要发送到其他 window 的数据,它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化
targetOrigin:指定哪些窗口能接收到消息事件,其值可以是 *(表示无限制)或者一个 URI,在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配 targetOrigin 提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送
transfer(可选):是一串和 message 同时传递的 Transferable 对象。这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权(一般不会使用)
message中的属性有:
data:从其他 window 中传递过来的对象
origin:调用 postMessage 时消息发送方窗口的 origin . 这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成,这个 origin 不能保证是该窗口的当前或未来 origin,因为 postMessage 被调用后可能被导航到不同的位置
source:对发送消息的窗口对象的引用; 您可以使用此来在具有不同 origin 的两个窗口之间建立双向通信
上代码
发送方:
// 先通过打开窗口,因为根据网速和页面大小,打开网页的时间不确定,最开始使用setTimeout在间隔
// 2000ms后发送data,发现网速一卡就接受失败,所以这里在接受方页面load加载完成后,再发送加载完成的信息到发送方,发送方
// 接受到信息后再传输数据过去
const domain = ('http://localhost:8082/#/progress-bar')
// 通过message监听事件接受到信息后再postMessage
(
'message',
(e) => {
domain .postMessage({token: ('token'),uuid,},
'http://localhost:8082'
)}, false)
接受方
('load', () => {
// 是对父页面,也就是跳转前页面的引用参数,在load完成后传输数据过去
('子页面加载完毕', 'http://192.168.0.149:5173')
})
('message', (e) => {
// 当是发送方的端口号时再接受数据
if ( === 'http://192.168.0.149:5173') {
(, '接受到的数据')
}
}, false)
优化方案
每次用完此监听事件可以在接收或者发送完数据后对此监听事件进行移除
('message', function)
最后
如果有帮助到各位大佬们,记得双击收藏关注点赞,关注必回!!!