请选择 进入手机版 | 继续访问电脑版

猫先森网络资源站

 找回密码
 立即注册
查看: 1180|回复: 183

[HTML/Xhtml] html5使用window.postMessage进行跨域实现数据交互的一次实战

  [复制链接]
等级头衔

等級:论坛元老

Rank: 8Rank: 8

积分成就
积分
2956
金钱
45
人气
45
贡献
2911
主题
2911
精华
0
猫币
0
违规
0
注册时间
2021-1-14
最后登录
2021-1-14

快捷版块
版块
网站源码
版块
游戏源码
版块
商业源码
版块
SEO新闻
版块
SEO教程
版块
SEO程序
功能
猫币提现

发表于 2021-2-24 15:36:38 | 显示全部楼层 |阅读模式
这篇文章主要介绍了html5使用window.postMessage进行跨域实现数据交互的一次实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
                                       
                                               
                                               
                                       
                                       
                                                背景
在一个App内嵌的H5中,产品希望在页面的下放设置一个区域,里面展示运营同学通过活动搭建平台生成的教学页面,页面由运营同学自己搭建、替换,产品同学希望H5中能完整展示这个教学页面的内容。
从业务需求上描述,就是一个H5(A页面)内需要通过iframe加载另一个H5页面(B页面)。但是从技术角度来看就有以下几点需要注意的地方:

   
  • B页面的高度不确定,B页面由活动搭建平台生成,至于展示的内容是什么、有多少并不知道。
       
  • A页面和B页面是不同源的,因此无法直接通过iframe的contentWindow获取到B页面的尺寸。

    2021224153150000.jpg

    2021224153150000.jpg


    解决方法
    其实接合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页面不需要做任何事情。

    2021224153404048.jpg

    2021224153404048.jpg


    前置知识
    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跨域内容请搜索脚本之家以前的文章或继续浏览下面的相关文章,希望大家以后多多支持脚本之家!

  • 回复

    使用道具 举报

    等级头衔

    等級:新手上路

    Rank: 1

    积分成就
    积分
    0
    金钱
    1
    人气
    0
    贡献
    0
    主题
    0
    精华
    0
    猫币
    0
    违规
    0
    注册时间
    2021-1-14
    最后登录
    2021-4-15

    快捷版块
    版块
    网站源码
    版块
    游戏源码
    版块
    商业源码
    版块
    SEO新闻
    版块
    SEO教程
    版块
    SEO程序
    功能
    猫币提现

    发表于 2021-3-15 18:28:29 | 显示全部楼层
    脚本之家楼主,我告诉你一个你不知道的的秘密,有一个牛逼的网站,影视频道的网站所有电影和连续剧都可以免费看的。访问地址:http://tv.mxswl.com

    回复

    使用道具 举报

    等级头衔

    等級:新手上路

    Rank: 1

    积分成就
    积分
    0
    金钱
    6
    人气
    0
    贡献
    0
    主题
    0
    精华
    0
    猫币
    0
    违规
    0
    注册时间
    2021-1-14
    最后登录
    2021-4-14

    快捷版块
    版块
    网站源码
    版块
    游戏源码
    版块
    商业源码
    版块
    SEO新闻
    版块
    SEO教程
    版块
    SEO程序
    功能
    猫币提现

    发表于 2021-3-15 18:34:12 | 显示全部楼层
    帖子很有深度!

    回复

    使用道具 举报

    等级头衔

    等級:新手上路

    Rank: 1

    积分成就
    积分
    2
    金钱
    0
    人气
    0
    贡献
    1
    主题
    1
    精华
    0
    猫币
    1
    违规
    0
    注册时间
    2021-1-14
    最后登录
    2021-1-14

    快捷版块
    版块
    网站源码
    版块
    游戏源码
    版块
    商业源码
    版块
    SEO新闻
    版块
    SEO教程
    版块
    SEO程序
    功能
    猫币提现

    发表于 2021-3-15 19:01:35 | 显示全部楼层
    林子大了,什么鸟都有了啊!

    回复

    使用道具 举报

    等级头衔

    等級:新手上路

    Rank: 1

    积分成就
    积分
    0
    金钱
    0
    人气
    0
    贡献
    0
    主题
    0
    精华
    0
    猫币
    0
    违规
    0
    注册时间
    2021-1-14
    最后登录
    2021-1-14

    快捷版块
    版块
    网站源码
    版块
    游戏源码
    版块
    商业源码
    版块
    SEO新闻
    版块
    SEO教程
    版块
    SEO程序
    功能
    猫币提现

    发表于 2021-3-15 19:15:57 | 显示全部楼层
    世界末日我都挺过去了,看到脚本之家楼主我才知道为什么上帝留我到现在!

    回复

    使用道具 举报

    等级头衔

    等級:新手上路

    Rank: 1

    积分成就
    积分
    0
    金钱
    0
    人气
    0
    贡献
    0
    主题
    0
    精华
    0
    猫币
    0
    违规
    0
    注册时间
    2021-1-14
    最后登录
    2021-1-14

    快捷版块
    版块
    网站源码
    版块
    游戏源码
    版块
    商业源码
    版块
    SEO新闻
    版块
    SEO教程
    版块
    SEO程序
    功能
    猫币提现

    发表于 2021-3-15 19:21:22 | 显示全部楼层
    脚本之家楼主,您主治大夫在到处找您呢!

    回复

    使用道具 举报

    等级头衔

    等級:新手上路

    Rank: 1

    积分成就
    积分
    0
    金钱
    2
    人气
    0
    贡献
    0
    主题
    0
    精华
    0
    猫币
    0
    违规
    0
    注册时间
    2021-1-14
    最后登录
    2021-4-13

    快捷版块
    版块
    网站源码
    版块
    游戏源码
    版块
    商业源码
    版块
    SEO新闻
    版块
    SEO教程
    版块
    SEO程序
    功能
    猫币提现

    发表于 2021-3-15 19:36:44 | 显示全部楼层
    知识就是力量啊!

    回复

    使用道具 举报

    等级头衔

    等級:新手上路

    Rank: 1

    积分成就
    积分
    0
    金钱
    1
    人气
    0
    贡献
    0
    主题
    0
    精华
    0
    猫币
    0
    违规
    0
    注册时间
    2021-1-14
    最后登录
    2021-4-13

    快捷版块
    版块
    网站源码
    版块
    游戏源码
    版块
    商业源码
    版块
    SEO新闻
    版块
    SEO教程
    版块
    SEO程序
    功能
    猫币提现

    发表于 2021-3-15 23:45:10 | 显示全部楼层
    脚本之家楼主你想太多了!

    回复

    使用道具 举报

    等级头衔

    等級:新手上路

    Rank: 1

    积分成就
    积分
    2
    金钱
    1
    人气
    0
    贡献
    1
    主题
    1
    精华
    0
    猫币
    1
    违规
    0
    注册时间
    2021-1-14
    最后登录
    2021-4-13

    快捷版块
    版块
    网站源码
    版块
    游戏源码
    版块
    商业源码
    版块
    SEO新闻
    版块
    SEO教程
    版块
    SEO程序
    功能
    猫币提现

    发表于 2021-3-16 10:12:10 | 显示全部楼层
    哥回复的不是帖子,是寂寞!

    回复

    使用道具 举报

    等级头衔

    等級:新手上路

    Rank: 1

    积分成就
    积分
    0
    金钱
    1
    人气
    0
    贡献
    0
    主题
    0
    精华
    0
    猫币
    0
    违规
    0
    注册时间
    2021-1-14
    最后登录
    2021-4-13

    快捷版块
    版块
    网站源码
    版块
    游戏源码
    版块
    商业源码
    版块
    SEO新闻
    版块
    SEO教程
    版块
    SEO程序
    功能
    猫币提现

    发表于 2021-3-16 11:25:27 | 显示全部楼层
    脚本之家楼主,我告诉你一个你不知道的的秘密,有一个牛逼的网站,他卖的服务器是永久的,我们的网站用 服务器都是在这家买的,你可以去试试。访问地址:http://fwq.mxswl.com

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    快速回复 返回顶部 返回列表