您现在的位置是:网站首页> 编程资料编程资料
html5使用window.postMessage进行跨域实现数据交互的一次实战详解HTML5 window.postMessage与跨域
2021-08-30
1238人已围观
简介 这篇文章主要介绍了html5使用window.postMessage进行跨域实现数据交互的一次实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
背景
在一个App内嵌的H5中,产品希望在页面的下放设置一个区域,里面展示运营同学通过活动搭建平台生成的教学页面,页面由运营同学自己搭建、替换,产品同学希望H5中能完整展示这个教学页面的内容。
从业务需求上描述,就是一个H5(A页面)内需要通过iframe加载另一个H5页面(B页面)。但是从技术角度来看就有以下几点需要注意的地方:
- B页面的高度不确定,B页面由活动搭建平台生成,至于展示的内容是什么、有多少并不知道。
- A页面和B页面是不同源的,因此无法直接通过iframe的contentWindow获取到B页面的尺寸。

解决方法
其实接合1、2点,核心就是需要在A页面获取到B页面的高度,然后调整A页面展示区域的高度,实现在A页面完整展示B页面的功能。
初步想法
这里我想到了使用window.postMessage去解决不同域下页面通讯的问题。A页面不能主动通过不同域的contentWindow获取到B页面的尺寸,那么,让B页面通过window.postMessage通知页面A就好了,自己获取自己的总能获取到。
但是问题来了,B页面不是确定的,是由运营通过搭建平台生成的,也就是说,是没办法在B页面通过代码入侵的方式通知A页面。
进一步想法
实际上,搭建平台中的组件是可实现的。可以通过开发一个“iframe通讯组件”,再基于这个组件搭建一个C页面作为“桥”。那么,因为B页面和C页面都是由搭建平台生成,是同域的,那么,C页面可以主动地通过iframe的contentWindow获取到B页面的高度。最后,A页面和C页面虽然是跨域,但是通过window.postMessage可以实现跨域通讯,A页面只需要监听message事件即可。
有了这样一个作为“桥”的C页面,那么以后不管运营同学通过搭建平台发布什么页面,A页面都是可以完整展示B页面的内容,并且B页面不需要做任何事情。

前置知识
postMessage
otherWindow.postMessage(message, targetOrigin, [transfer]);
首先,otherWindow是一个其他窗口的引用,什么情况下可以获得其他窗口呢?可以通过iframe的contentWindow、window.opener(这个页面从哪里打开的)以及window.parent(A页面通过iframe嵌套C页面时,C页面可通过window.parent获取A页面的引用)。
message是一个对象,简单来说,传输时会默认做深拷贝,所以不用担心引用的问题。具体拷贝规则: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm (又发现了一个实现深拷贝的方式?)
targetOrigin通过这个参数来实现哪些窗口能收到这个消息,如果为'*',那么就是都可以。可以传入一个URI字符串,会通过协议、主机地址、端口去比对,三者中有一者不匹配,就传不过去。
更详细的可以阅读: https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage
实现
C 页面
先来实现作为“桥”的C页面,这个页面是主要的实现。
首先,C页面是被A页面通过iframe加载的,因此,这里通过获取URL上参数的方式,获得B页面的链接。
const src = getQueryString('src'); 获取到链接后,C页面通过iframe的方式加载B页面,并且添加到文档中。为了能够获取到B页面的链接,我们需要在B页面onload事件触发后再获取,此时页面上的图片已经加载完毕。
const iframe = document.createElement('iframe'); iframe.addEventListener('load', () => { // 关键步骤 }); iframe.src = src; iframe.style.visibility = 'hidden'; document.body.appendChild(iframe); 最后实现onload事件中的关键步骤:获取B页面的高度、通过 postMessage 发送高度参数给A页面。
获取B页面的高度:
const doc = iframe.contentDocument; const iframeHeight = Math.max(doc.body.clientHeight, doc.documentElement.clientHeight, doc.body.scrollHeight, doc.documentElement.scrollHeight);
通过 window.parent 获取A页面的 window 对象的引用,最后通过window.parent.postMessage向A页面发送消息:
if (window.parent) { window.parent.postMessage( { type: 'resize-iframe', data: { height: iframeHeight } }, '*' ); } A 页面
A页面做的事情就比较简单了,就是一个iframe加载B页面,另一个iframe加载C页面。通过message事件获取最终高度,调整B页面iframe的高度。
const resizeHandler = (e) => { const data = e.data; if (data.type === 'resize-iframe') { const { height } = data.data; // 这里设置了最小400高度 this.height = Math.max(400, height); } }; window.addEventListener('message', resizeHandler); 总结
通过window.postMessage的方式进行跨域其实也是第一次去实践,以前总是在一些面试复习资料中了解到,但日常的跨域基本上都是用CORS的场景(其实CORS都不用前端做什么事情),甚至连JSONP都没有。
业务中能用到不常用的方式解决问题,感觉也是挺好的,起码知识不会停留在字面上~
到此这篇关于html5使用window.postMessage进行跨域实现数据交互的一次实战的文章就介绍到这了,更多相关html5 window.postMessage跨域内容请搜索以前的文章或继续浏览下面的相关文章,希望大家以后多多支持!
相关内容
- html5表单的required属性使用wordpress添加Html5的表单验证required方法小结html5的input的required使用中遇到的问题及解决方法html5中valid、invalid、required的定义
- html5调用摄像头实例代码Html5调用手机摄像头并实现人脸识别的实现html5调用摄像头功能的实现代码HTML5混合开发二维码扫描以及调用本地摄像头HTML5调用手机摄像头拍照的实现思路及代码HTML5 Canvas+JS控制电脑或手机上的摄像头实例
- HTML5页面音频自动播放的实现方式html5 video全屏播放/自动播放的实现示例html5中嵌入视频自动播放的问题解决html5自动播放mov格式视频的实例代码解决HTML5中的audio在手机端和微信端的不能自动播放问题HTML5 解决苹果手机不能自动播放音乐问题有关HTML5中背景音乐的自动播放功能HTML5页面音视频在微信和app下自动播放的实现方法
- Html5大屏数据可视化开发的实现html5实现点击弹出图片功能html5 录制mp3音频支持采样率和比特率设置html5表单的required属性使用html5调用摄像头实例代码HTML5页面音频自动播放的实现方式Html5大屏数据可视化开发的实现html实现弹窗的实例HTML5来实现本地文件读取和写入的实现方法HTML 罗盘式时钟的实现HTML5简单实现添加背景音乐的几种方法
- html实现弹窗的实例css实现弹窗上下左右居中且背景透明锁定窗口效果CSS实现带遮罩层可关闭的弹窗效果CSS导航栏及弹窗示例代码弹窗居中的简单实现方法不是所有弹窗都是流氓 关于网站弹窗的设计技巧利用js+css简单实现半透明遮罩弹窗网页设计中的弹窗与浮层的设计
- HTML5来实现本地文件读取和写入的实现方法利用html5 file api读取本地文件示例(如图片、PDF等)浅谈HTML5 FileReader分布读取文件以及其方法简介html5读取本地文件示例代码
- HTML 罗盘式时钟的实现Html5 canvas实现粒子时钟的示例代码HTML写一个网页动态时钟HTML5实现可缩放时钟代码用HTML5的canvas实现一个炫酷时钟效果使用html5 canvas 画时钟代码实例分享用HTML5制作数字时钟的教程html5绘制时钟动画html5时钟实现代码
- HTML5简单实现添加背景音乐的几种方法有关HTML5中背景音乐的自动播放功能利用HTML5实现使用按钮控制背景音乐开关
- canvas绘制折线路径动画实现html5如何在Canvas中实现自定义路径动画示例
- Html5生成验证码的示例代码利用html5 canvas破解简单验证码及getImageData接口应用
