iframe跨域通信实战

王信
• 阅读 2715

"长时间不写文章,开头的方式总是那么出奇的相似",最近很忙,好久没写博客了啊(是不是?)。
更换工作已经有三个月有余,这段三个月把过去三年没加过的班都加了一次。收获挺多,发现的问题也挺多。
一直也在思考一些问题:
如何把自己遇见的问题好好的理解并且总结?
如何很好的学习新知识,不只是停留在用的基础上?
……

上面的问题我一直在尝试更适合我的方法,暂时就不扯淡了,先尝试一下把这段时间过程中遇见的问题总结下,然后争取给看文的你以我的方式描述清楚,我想我应该就把第一个问题解决了。

简介

项目实战中postMessage的使用

问题描述

前提:我们的项目与兄弟团队的项目都是基于同一套基础框架开发,只是在视图层我们有各自的一套东西。
项目是一个hybrid项目,目前是以h5的形式在开发,后期可以轻松转为hybrid。目前已经以h5的形式上线到自家公众号,大致是在硬件上产出一份报告,h5把报告的内容展示出来。
新需求是,把报告推给兄弟团队的APP,在APP内也能打开我们的报告进行查看报告然后点评。
兄弟团队为了最小的改动实现这个功能,用了iframe的形式打开我们推过去的报告链接,问题就出在报告能在兄弟团队的APP中打开却不能跳转链接,问题是因为我们的基础框架提供的forward方法在app内是通过native的方式来跳转,但是我们的协议不会被兄弟团队的app识别,简单说就是跳转直接被拦截了。
经过几番商量,商定出三个解决方案:

  • iframe跨域通信
  • 他们重新做一套(不可取的备选)
  • 我们来实现他们的点评业务(业务交错不可取)

杂货铺中的知识点

很明显我们更倾向于第一种方式,仿佛记得之前总结过类似的一篇文章同源策略和跨域知识点学习,当时完全是参考知识点进行的一次搬移,现在看来完全还是没有透彻理解。

  • 同源:同源即需要协议主机名(域名或者ip)端口相同。
  • 跨域:域名不一致了,自然是不同源的,这种情况下要通信何解呢?

postMessage派上用途。
h5模式下子页面跳转协议可以正常使用history模式或者非单页模式跳转。(知识点:这种情况下iframe的src不会随iframe内跳转链接的变化而变化,父页面不能监听到子页面内的页面变化)
hybrid模式下链接跳转被拦截,页面表现就是链接点不了,如何让父元素知道我点了什么链接,然后来切换页面,他们做url更换,来实现跳转并且支持切换页面操作,如此我们就需要子页面给父页面发送一条message告诉它我要跳转到哪一个页面。

实战知识点

页面跳转中我们使用了$forward方法进行收口,所有的跳转都需要经过这个方法(对于收口的好处这里就体现出来了),我只需要判断ua在跳转前执行以下消息发送的方法。

/**
 * 页面跳转方法
 * @param page 要跳转的页面名称
 * @param param 跳转时需要额外携带的参数
 */
$forward(page, param) {
    // _ extend getUrlParam getUrlRule loadPage isHybrid 省略
    var param = _.extend(_.getUrlParam(), param);
    let url = _.getUrlRule(page, param);
    if(isHybrid) {
        _.requestHybrid({
            // 省略
        });
    } else {
        _.loadPage(url);
    }
}

在跳转前我们先检测一下ua,判断是否是在兄弟团队app内做特殊处理

let ua = navigator.userAgent.toLowerCase(),
    isFriendHybrid = /friend_hybrid_\w+_(\d*\.?)+/.test(ua);
if(isFriendHybrid) {
    window.top.postMessage({
        tag: 'forward',
        url: url
    }, '*')
} else {
    this.$forward();
}

在兄弟团队的父页面只需要监听message事件获取我传递过去的消息做特殊处理即可

window.addEventListener('message', function(e) {
    console.log(e.data);
    // {tag: 'forward', url: ……}
})

例如在一个特殊位置我会在没有pdf的时候直接弹出调试“暂时没有报告”,用户点击之际显示的是我弹出的toast,由于嵌入后有兼容问题,于是我们又约定了一个方法。

window.top.postMessage({
    tag: 'showtoast',
    content: '暂时没有报告'
}, '*')

这应该就是一个典型的iframe跨域通信例子。

demo

https://jsfiddle.net/unoffici...

点赞
收藏
评论区
推荐文章
Chase620 Chase620
4年前
React Hook实战项目(含axios封装,双层路由的使用,redux的使用)
好久没写文章了,今天就来介绍下最近写的reacthook的练手项目,用到相关的技术有以下:antd,reactrouterdom,reduxthunk,axios,hook,下面就开始介绍自己的项目了。项目比较简单,只是把架子搭好了,后面会继续完善。这是我的项目地址https://github.com/Hongguobin/createa
Easter79 Easter79
3年前
springboot的跨域
https://www.cnblogs.com/520playboy/p/7306008.html1、对于前后端分离的项目来说,如果前端项目与后端项目部署在两个不同的域下,那么势必会引起跨域问题的出现。针对跨域问题,我们可能第一个想到的解决方案就是jsonp,并且以前处理跨域问题我基本也是这么处理。但是jsonp方式也同样有不足,不管是对
东方客主 东方客主
4年前
20 张图彻底弄懂 HTTPS 的原理
前言近年来各大公司对信息安全传输越来越重视,也逐步把网站升级到HTTPS了,那么大家知道HTTPS的原理是怎样的吗,到底是它是如何确保信息安全传输的?网上挺多介绍HTTPS,但我发现总是或多或少有些点有些遗漏,没有讲全,今天试图由浅入深地把HTTPS讲明白,相信大家看完一定能掌握HTTPS的原理,本文大纲如下:HTTP为什么不安全
Wesley13 Wesley13
3年前
ASP.NET安全问题--ASP.NET生命周期中的验证以及身份验证模块
                               ASP.NET生命周期中的验证以及身份验证模块       前言:最近一直很忙,没有来得及把之前的文章写完,已经有不少朋友在给我留言催我了,很感谢朋友们的关注,也跟大家说声对不起!系列文章链接:ASP.NET开发安全问题(https://www.oschina.net/
Wesley13 Wesley13
3年前
gnome
从2014.8.14到2014.11.11,在David的帮助下共修复了两个bug。三个月以来,也有过挫折,也想过放弃,但更多的是编程过程中的喜悦和坚持。三个月,自己从其中收获了很多。好久也没有来写blog了,就着刚刚修复一个bug的小空闲,来这里记录下自己的收获。第一个bug的链接:https://bugzilla.gnome.org/show
Stella981 Stella981
3年前
Spring Boot 中三种跨域场景总结
@\toc\跨域这个问题松哥之前写过文章,但是最近收到小伙伴们的一些问题,让我发现之前的总结不够全面,因此打算再写一篇文章,来和大家分享一下SpringBoot中的跨域问题。这次我把SpringBoot中的跨域问题分为了三个场景:普通跨域SpringSecurity跨域OAuth2跨域分
Wesley13 Wesley13
3年前
IJCAI
前言从去年11月下旬开始入坑机器学习,到现在也已经有半年了,一开始就是学习机器学习理论方面的知识,但是学到两三个月的时候总觉得没点实际操作,所以感到知识点很空洞。自己是自学机器学习的,周围又没有实际项目可以做,能拿来练手的恐怕只有各种数据算法竞赛了。今年二月到三月第一次参加了kaggle上的Toxic文本分类比赛,但是由于自身经验严重不足,和理论
Wesley13 Wesley13
3年前
2019,我的这一年,在校研究生做到年入20W,另送我的读者2000元现金红包
2019年过去了,到了该总结这一年的时候了,回顾这一年,自己做出了很多的努力,也得到了一些收获,当然,每一次回顾的时候,总是会发现有很多的地方是不足的,这也是不可避免的,每一次回顾的时候,只希望自己最希望做到的事情可以如愿,那就心满意足了。公众号第一件事情,我还是想谈一下公众号:好好学java,这也是我这一年多的时间的重心所在,这一年的收
你还在为SFTP连接超时而困惑么? | 京东云技术团队
1\.前言在最近的项目联调过程中,发现在连接上游侧SFTP时总是需要等待大约10s的时间才会出现密码输入界面,这种长时间的等待直接导致的调用文件接口时连接sftp超时问题。于是决定自己针对该问题进行一下排查,查询了相关资料,并逐个试验了一下网上提供的解决
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
深入跨域 - 解决方案
1前言前文《深入跨域从初识到入门》中,大家已经对同源与跨域的产生历史与重要性等有了一个初步的了解了,那么我们应该如何解决在日常开发中遇到的跨域引起的问题呢?2一览图我们将日常开发中的跨域解决方案大体分为两类:iframe跨域与API跨域:3iframe跨域