从iframe高度自适应了解postMessage

背景:

iframe在我们的项目里用的比较多,也是为了复用一些代码,在这样的情况下,iframe的高度自然而然就成了一个大问题,不合适的iframe高度会使页面出现2个及以上的滚动条,这对用户体验及美观(前端的强迫症)来说都是比较痛苦的。因此我们需要让iframe的高度达到一个合适的高度,从而达到除了外部的滚动条外,不产生多余的其他滚动条。

如何用postMessage来实现?

postMessage的实现类似sub、pub,首先需要在父页面绑定一个接收事件,接收来自子页面的message事件,一般会用origin来判断是否来自期望的子页面。

父页面接收消息

父页面伪代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
window.addEventListener('message', function(e){
/*
* e里面会有一些参数,我们用到以下两个
* e.origin 来源
* e.data 参数
*/

//判断origin是否来自xxx,是则将data传递过去
if(e.origin == 'xxx'){
callback(e.data);
}
});

function callback(data) {
//判断事件名,执行相应的操作
if(data.eventName == 'changeHeight'){
changeHeight(data.height);
}
}

function changeHeight(height) {
var selector = 'xxx';
selector.height = height;
}

子页面发送消息

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

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

  2. data 将要发送到其他 window的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。

  3. targetOrigin 通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串”“(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的orign属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。

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

子页面伪代码如下:

1
2
3
4
5
6
7
var data = {
eventName: 'changeHeight',
height: $('body').height()
};

var targetOrigin = 'https://www.sb.com';
window.postMessage(data, targetOrigin);

以上,我们就完成了使用postMessage来改变父页面的高度。

注意事项

  • 使用message来接收消息时,为了安全起见,请对origin进行判断,防止不期望的页面发起攻击

  • 使用message来发送事件时,请明确targetOrigin,防止第三方截获你发送的数据

坚持原创技术分享,您的支持将鼓励我继续创作!