最近在写Webview,涉及到了web与客户端的数据交互,因此也就有了使用postMessage的理由。
先贴上postMessage的文档: https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage
文档中介绍了postMessage方法的入参及使用方式,但是我在理解中存在了个误区,记录下来希望能帮和我一样理解误区了的朋友一起走出误区
误区:A页面使用window.postMessage指定了targetOrigin,TargetOrigin的页面addEventListener后,所在窗口能接收到消息
<!-- A.html----www.a.com -->
<script>
window.postMessage('i am a', 'http://wwww.b.com');
</script>
<!-- B.html----www.b.com -->
<script>
window.addEventListener('message', function(e) {
if (e.origin === 'http://www.a.com') {
console.log(e.data);
}
})
</script>
如上图代码所示,在chrome打开两个tab页,一个tab为www.a.com, 另一个tab为www.b.com。结果是B.html中监听不到A.html中发的消息。
说好的跨源通信呢!
上面的示列,不仅跨源,还跨了tab进程,他们处于两个隔离的环境,所以使用postMessage与监听message事件应该处于同一个window对象。所以应该是B.html中的window.addEventListener监听的message事件只能是由B.html中的window对象调用的postMessage发出的message事件或者window.dispatch(new MessageEvent('message', {data: 'haha'}))。
定义: 所谓的跨源通信指的是A.html中能够拿到B.html的window对象使用postMessage对b.html发送消息。
A.html中获取B.html中的window情况:
1. A为B的子页面: windowB = window.parent
2. B为A的子window--iframe内嵌B: windowB = window.querySelector([iframe的Id]).contentWindow
2. B为A的子window--window.open打开的window: windowB = window.open('http://www.b.com',);
以上为个人理解,如果有不对的地方欢迎大家指出共同学习。