前端进程间通讯的渗透之术
时间:2022-07-26
本文章向大家介绍前端进程间通讯的渗透之术,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前端渗透的应用场景有很多,比如在《魔改npm私有仓库 》一文中就介绍了如何在框架中植入私有代码,让逻辑线程和主线程激情博弈。这次介绍另外一种进程间渗透内存的玩法,适用于网页和iframe常见的博弈。
进程间的通讯方式
父页面和子页面(iframe)处于2个不同的进程(即使在同一个域),进程之间的通讯必须通过每个进程内【事件监听所在的线程】来完成。最重要的是,通讯时传输的数据格式必须是序列化的格式,序列化格式指【一维】【线性】的数据类型比如字符串、字节流等,在浏览器中有这么几种序列化格式可选:
- 字符串:可以传普通的文本信息
- JSON:最流行的格式,JavaScript原生支持
- 结构化克隆算法:可以打包常见的JS对象,postMessage使用的算法
- 二进制格式:性能很高,比如我的Zipack,但需要引入额外的包
下面介绍2种方法(可能性),可以让父页面以最大的自由度读写iframe的内容,这两种方法的优点是:子页面的开发商只需要一点点的配合就能实现,主动权掌握在父页面手中。缺点是:需要熟悉子页面的结构,本质上属于代码渗透,可能有性能影响。
直接访问同域iframe的内存
有一种特殊情况下,不同的进程可以共享内存空间:如果父页面和iframe同域,问题就简单多了,也不必传输序列化数据了,父页面可以直接访问并修改iframe的全局作用域window对象(因为浏览器认为同域之间相互信任)。
比如想去掉iframe中的导航栏(nav元素),可以通过下面的代码实现:
-
iframe.contentDocument.querySelector('nav').remove();
如果只是想隐藏掉,可以这样:
-
iframe.contentDocument.querySelector('nav').style.display='none';
想点击某个按钮(button元素):
-
iframe.contentDocument.querySelector('button').click();
同理,iframe中也可以直接访问父页面的全局环境:
-
window.parent.document //document和DOM有关
异域下iframe暴露JS和CSS接口
如果不幸父页面和iframe不同域,那只能通过跨域的方式传序列化数据:父页面向子页面postMessage传值,子页面监听message事件。
比如希望传递一份CSS字符串,覆盖iframe中的样式:
-
iframe.contentWindow.postMessage({
-
type:
"css",
-
content:
`
-
body {
-
font-size: 25px !important;
-
} `
-
},
"*");
如果希望传一段js代码给iframe执行,可以这样:
-
iframe.contentWindow.postMessage({
-
type:
"js",
-
content:
`
-
alert('hello world') `
-
},
"*");
以上2种情况,iframe中可以这样监听:
- 动态创建<style>元素覆盖样式
- 利用eval()函数解释执行JS代码
-
window.addEventListener("message",
(event)
=>
{
-
if
(event.data.type ===
'css')
{
-
const style = document.createElement('style');
-
style.innerHTML =
event.data.content;
-
document.body.appendChild(style);
-
}
else
if
(event.data.type ===
'js')
{
-
eval(event.data.content);
-
}
-
},
false);
同理,iframe向父页面发送数据:
-
window.parent.postMessage()
<完>
- zepto 基础知识(3)
- 1.[Andriod]之Andriod布局 VS WinPhone布局
- WordPress自定义url 中的“author” 别名
- ASP.NET 4 AppFabric 输出缓存提供程序
- WordPress 中禁止编辑“已发布”的文章
- Windows Server 2008 R2 网络负载平衡 (NLB)资料汇总
- 0.[Andriod]之从零安装配置Android Studio并编写第一个Android App
- WordPress 后台编辑文章页面添加自定义提示文字
- 使用json 和jQuery制作级联dropdownlist
- 在64位Windows 7/2008操作系统上部署32位的Web应用程序错误
- 云计算浪潮
- 2.[Andriod]Andriod Studio结合Visual Studio Emulator for Android调试Android App
- Windows Server AppFabric Caching
- zepto 基础知识(2)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 多个请求下 loading 的展示与关闭
- 第13期:表统计信息的计算
- 2019.8.15乘兴打Codeforces Round #569 (Div. 2)小记A题A. Alex and a Rhombus
- 2019.8.15乘兴打Codeforces Round #569 (Div. 2)小记B. Nick and Array
- 《hdu 免费馅饼》
- 技术分享 | 使用 pt-query-digest 分析慢日志
- 2019.8.15乘兴打Codeforces Round #569 (Div. 2)小记
- Codeforces Beta Round #14 (Div. 2)A. Letter
- Vue 改变数据,页面不刷新的问题
- R语言再保险合同定价案例研究
- 开发一个简单的 Vue 弹窗组件
- R语言模拟人类生活预期寿命动态可视化动画图gif
- Vue 动态添加路由及生成菜单
- R语言泊松回归对保险定价建模中的应用:风险敞口作为可能的解释变量
- Vue 页面权限控制和登陆验证