专栏首页Web行业观察前端进程间通讯的渗透之术

前端进程间通讯的渗透之术

前端渗透的应用场景有很多,比如在《魔改npm私有仓库 》一文中就介绍了如何在框架中植入私有代码,让逻辑线程和主线程激情博弈。这次介绍另外一种进程间渗透内存的玩法,适用于网页和iframe常见的博弈。


进程间的通讯方式

父页面和子页面(iframe)处于2个不同的进程(即使在同一个域),进程之间的通讯必须通过每个进程内【事件监听所在的线程】来完成。最重要的是,通讯时传输的数据格式必须是序列化的格式,序列化格式指【一维】【线性】的数据类型比如字符串、字节流等,在浏览器中有这么几种序列化格式可选:

  • 字符串:可以传普通的文本信息
  • JSON:最流行的格式,JavaScript原生支持
  • 结构化克隆算法:可以打包常见的JS对象,postMessage使用的算法
  • 二进制格式:性能很高,比如我的Zipack,但需要引入额外的包

下面介绍2种方法(可能性),可以让父页面以最大的自由度读写iframe的内容,这两种方法的优点是:子页面的开发商只需要一点点的配合就能实现,主动权掌握在父页面手中。缺点是:需要熟悉子页面的结构,本质上属于代码渗透,可能有性能影响。


直接访问同域iframe的内存

有一种特殊情况下,不同的进程可以共享内存空间:如果父页面和iframe同域,问题就简单多了,也不必传输序列化数据了,父页面可以直接访问并修改iframe的全局作用域window对象(因为浏览器认为同域之间相互信任)。

比如想去掉iframe中的导航栏(nav元素),可以通过下面的代码实现:

  1. iframe.contentDocument.querySelector('nav').remove();

如果只是想隐藏掉,可以这样:

  1. iframe.contentDocument.querySelector('nav').style.display='none';

想点击某个按钮(button元素):

  1. iframe.contentDocument.querySelector('button').click();

同理,iframe中也可以直接访问父页面的全局环境:

  1. window.parent.document //document和DOM有关

异域下iframe暴露JS和CSS接口

如果不幸父页面和iframe不同域,那只能通过跨域的方式传序列化数据:父页面向子页面postMessage传值,子页面监听message事件。

比如希望传递一份CSS字符串,覆盖iframe中的样式:

  1. iframe.contentWindow.postMessage({
  2. type: "css",
  3. content: `
  4. body {
  5. font-size: 25px !important;
  6. } `
  7. }, "*");

如果希望传一段js代码给iframe执行,可以这样:

  1. iframe.contentWindow.postMessage({
  2. type: "js",
  3. content: `
  4. alert('hello world') `
  5. }, "*");

以上2种情况,iframe中可以这样监听:

  • 动态创建<style>元素覆盖样式
  • 利用eval()函数解释执行JS代码
  1. window.addEventListener("message", (event) => {
  2. if (event.data.type === 'css') {
  3. const style = document.createElement('style');
  4. style.innerHTML = event.data.content;
  5. document.body.appendChild(style);
  6. } else if (event.data.type === 'js') {
  7. eval(event.data.content);
  8. }
  9. }, false);

同理,iframe向父页面发送数据:

  1. window.parent.postMessage()

<完>

本文分享自微信公众号 - WebHub(myWebHub),作者:金恒昱

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Google I/O 2018

    不知道各位有没有关注2018年的谷歌开发者大会,听了之后,让人对未来生活不得不充满了期待,智能时代已经接近了人们的生活!

    Jean
  • 虚幻运行时导入资产:泛型与模板的妙用

    在虚幻运行时,动态地选择资源文件(资产/Asset),读取并导入到UE系统,有若干种方法,比如importFileAsTexture2D可以读取图片文件封装成T...

    Jean
  • 降维打击(序列化)的流行手段

    上次介绍了message pack,一种非常有潜力的数据格式,市面上还有其他的格式比如json,xml,bson,甚至一些标记语言(html,markdown...

    Jean
  • iframe 解析

    简介:iframe在日常的开发中经常用到,本随笔在参考http://blog.csdn.net/cuew1987/article/details/1126515...

    郑小超.
  • iframe框架及优缺点

    HTML5不再支持使用frame,关于frame与iframe的区别,可以参阅 iframe与frame的区别

    WindrunnerMax
  • 根据获取内部元素的高度,设置iframe的高度

    德顺
  • 深入理解iframe

    iframe 用于在页面内显示页面,使用 <iframe> 会创建包含另外一个文档的内联框架(即行内框架)

    Leophen
  • 真正解决iframe高度自适应问题

    拿到这个对象,就可以根据正常网页的方法拿到嵌入(子)网页的文档高度,然后把值附给父页面的iframe的height。

    yuezhongbao
  • 动态创建iframe标签页并监控其加载成功(onload)的事件

    Jerry Wang
  • 多Iframe版后台,在一个iframe切换到另一个iframe,同时刷新

    当我们使用多标签iframe的后台管理模板时,需要在一个iframe中跳转到另一个iframe,并且对新iframe进行操作,这篇文章记录一下我在开发过程中编写...

    宣言言言

扫码关注云+社区

领取腾讯云代金券