postMessage到底有多好用

postMessage是什么?

postMessage()方法容许来自不一样源的脚本采用异步方式进行有限的通讯,能够实现跨文本档、多窗口、跨域消息传递。html

Html5中的postMessage解决跨域,跨窗口消息传递

postMessage的优势html5

  1. 两个跨域页面的消息传递
  2. 多窗口之间的消息传递
  3. 嵌套iframe的数据传递
postMessage()

postMessage()方法容许来自不一样源的脚本采用异步方式进行有限的通讯,能够实现跨文本档、多窗口、跨域消息传递。 postMessage(data,origin)方法接受两个参数json

  1. data:要传递的数据,html5规范中提到该参数能够是JavaScript的任意基本类型或可复制的对象,然而并非全部浏览器都作到了这点儿,部分浏览器只能处理字符串参数,因此咱们在传递参数的时候须要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js能够实现相似效果。
  2. origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,因此能够不写,这个参数是为了安全考虑,postMessage()方法只会将message传递给指定窗口,固然若是愿意也能够建参数设置为"*",这样能够传递给任意窗口,若是要指定和当前窗口同源的话设置为"/"。

例如:跨域

// A页面 [http://a.com]
const data = document.getElementById('name').value;
window.frames[0].postMessage(data,'http://b.com');
复制代码

在B页面监听message事件,获取传递过来的数据浏览器

// B页面 [http://b.com]
window.addEventListener('message', function(ev) {
    // 当咱们是父子窗口进行消息传递时,可使用此判断,只接受父窗口传递来的消息,
    if (ev.source !== window.parent) return;
    var data = ev.data;
    console.info('message from parent:', data);
}, false);
复制代码

经过这样的一个传递和接受的过程能够实现一个完整的消息传递。无论A,B是否跨域,是否存在嵌套关系,均可以使用postMessage的方式实现消息传递。安全

MessageEvent的属性
  • data:从源端传递来的message
  • source:发送消息的窗口对象
  • origin:发送消息窗口的源(协议+主机+端口号)

当咱们只处理某些源发送过来的消息时,咱们可使用origin来作判断,只处理某一些源的message,这样方便过滤一些没必要要的值。bash

解决问题

最近遇到一个问题,本身的代码【A_child】是经过Iframe的方式放在A系统中的,由于代码中须要A系统登陆时的用户信息去获取资源,因此须要A系统中的cookie信息。目前的处理方式就是讲个人代码部署到A系统的服务器上,而后指定不一样的端口,这样使用嵌入iframe的方式实现cookie共享。可是缺点就是每次更新代码都须要A系统的负责人去作更新。耗费了大量的人力和时间成本。服务器

注意:相同的域名,不一样的端口能够共享cookie信息。微信

最近为了减轻本身的工做负担,决定写一个中间层页面,放在A系统下,菜单的指向不变,只是在中间层的页面中在作一次iframe嵌套,而且在这个页面中将A系统中的cookie信息使用postMessage的方式发送给origin端。cookie

注意:由于我本身代码进入时就须要带着用户信息请求表格数据,因此页面的全部操做必须在收到message后才进行。因此就有了下面的这个代码

window.addEventListener('message', (ev) => {
    if (ev.source !== window.parent) return;
    const data = ev.data; 
    ...
    ...
    ...
    Vue.prototype.userInfo = data;
    new Vue({
        el: '#app',
        router,
        store,
        render: h => h(renderComponents),
    });
}, false);
复制代码
固然解决嵌套iframe跨域传值的问题,还有另外的两个方法。
  1. 使用hash值,将须要传递的值data放在iframe中src的hash中。
  2. 子页面传值给父页面,能够借助C页面【C和A必须时同域的】,A中嵌套B,B中嵌套C,B要想A传值,可使用C做为一个事件BUS,B中的数据先传递给C,而后在经过C传递数据给A。【此方法筱筱没用过啊】,大概方法是这样的。
总结

html5新增的特性,postMessge主要是更方便的解决了多页面的消息传递,而且有效解决了跨域问题。使用起来更加的简单方便。不过根据本身的需求选择不一样的处理方式。

欢迎关注微信公众号

相关文章
相关标签/搜索