HTML5 之跨域通讯(postMessage)

更新日期: 2019-07-09阅读: 2.5k标签: 通讯

很多情况下,我们受到浏览器的安全策略限制。如何能规避此限制,并且能安全的使用跨域通讯,这就不得不介绍一下 postMessage 了。


一、关于 postMessage

window.postMessage() 方法可以安全地实现跨源通信。

通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为 https),端口号( 443 为 https 的默认值),以及主机 (两个页面的模数 Document.domain 设置为相同的值) 时,这两个脚本才能相互通信。

window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。


二、理解过程

window.postMessage() 方法被调用时,会在所有页面脚本执行完毕之后向目标窗口派发一个 MessageEvent 消息。 该 MessageEvent 消息有四个属性:

1. message 属性表示该 message 的类型;

2. data 属性为 window.postMessage 的第一个参数;

3. origin 属性表示调用 window.postMessage() 方法时调用页面的当前状态;

4. source 属性记录调用 window.postMessage() 方法的窗口信息。


三、兼容性


通过上面的图片,我们可以看出来,几乎所有的浏览器都支持了 postMessage ,所以放心大胆的去使用吧。


四、用法简介

基本用例:

otherWindow.postMessage(message, targetOrigin, [transfer]);

1. otherWindow 
其他窗口的一个引用,比如 iframe 的 contentWindow 属性、执行 window.open 返回的窗口对象、或者是命名过或数值索引的 window.frames 。

2. message 
将要发送到其他 window 的数据。它将会被结构化克隆算法序列化。

这意味着我们可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。

3. targetOrigin 
通过窗口的 origin 属性来指定哪些窗口能接收到消息事件,其值可以是字符串 「*」(表示无限制)或者一个 URI 。

在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配 targetOrigin 提供的值,那么消息就不会被发送;

只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口。

我们举个例子,当用 postMessage 传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的 origin 属性完全一致,来防止密码被恶意的第三方截获。

如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的 targetOrigin,而不是 * 。

需要注意:不提供确切的目标将导致数据泄露到恶意站点。

4. transfer 
是一串和 message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。


五、事件监听

我们来看下面这段代码

window.addEventListener("message", receiveMessage, false);
function receiveMessage(event)
{
  // For Chrome, the origin property is in the event.originalEvent
  // object. 
  // 这里不准确,chrome没有这个属性
  // var origin = event.origin || event.originalEvent.origin; 
  var origin = event.origin
  if (origin !== "http://jartto.wang:8080")
    return;
  // ...
}

1. data 
从其他 window 中传递过来的对象。

2. origin 
调用 postMessage 时消息发送方窗口的 origin . 这个字符串由 协议、 :// 、域名、 : 端口号拼接而成。

例如 https://jartto.wang (隐含端口 443) 、 http://jartto.net(隐含端口 80) 、 http://jartto.com:8080 。请注意,这个 origin 不能保证是该窗口的当前或未来 origin ,因为 postMessage 被调用后可能被导航到不同的位置。

3. source 
对发送消息的窗口对象的引用, 我们可以使用此来在具有不同 origin 的两个窗口之间建立双向通信。


六、简单应用

1.监听 message 事件:

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event)
{
  console.log('get it !!!',event);
}

2.发送数据

window.postMessage({
    name: 'Jartto',
    say: 'hello~',
    arr: [1,2,3]
}, '*');


链接: https://www.fly63.com/article/detial/4122

IM即时通讯方案之第三方有哪些?

选择第三方即时通讯方案,我们应该从以下方面进行考虑:稳定性: 安全性: 功能性: 费用: 运维服务等,有哪些第三方IM即时通讯呢?比如:融云、JPush极光推送、网易云信、环信、云旺OpenIM等

https提供安全web通讯的原理

加密算法的分类:对称加密和非对称加密;如果选择对称加密,密码的共享(传输)过程不安全;如果选择非对称加密,加密速度慢。一个完美的解决方案:用对称加密的密钥用于加密数据,用户非对称加密来保护对称加密的密钥,

NodeJs 实现简单WebSocket 即时通讯

服务器的实现很简单,先装一个nodeJs的模块,叫nodejs-websocket , 直接在nodeJs命令行中敲入:npm install nodejs-websocket回车就可以安装好了,然后就可以开始建立服务器了,因为有了nodejs-websocket模块

H5与App的通讯方式

现在不管是桌面客户端还是移动客户端,都会夹杂着一部分H5页面,这种混合式的应用也是我们常说的Hybrid App。为什么会出现Hybrid App呢,早期是因为开发一个Android或iOS的客户端,需要的人力成本比较大,开发周期比较长

angular组件间通讯

一个Angular应用一般情况下包含多个组件,而且要让组件互相之间能进行通讯(数据传送),这样才能构成一个有机的完整系统。组件之间有几种典型的关系:父子关系、兄弟关系、没有直接关系

Vue3 中使用Event Bus

Vue 2 中要进行跨元件通讯,除了Vuex 以外的另一个常见手法是Event Bus,对于小型专案来说Event Bus 相当方便,仅需要$on、$emit两个语法就能进行跨元件通讯。而Vue 3 中移除了$on、$off等语法

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!