window.postMessage 解决 Vue 和 原生 html 混合开发的问题
由于历史项目的问题,原生采用的是 jquery,我们无法显著和快速的针对某个模块进行开发。当然,Vue 的话可以快速的帮我们解决这个问题
常见的解决方案有几种
- 1、iframe 嵌入
- 2、单页面使用 Vue Spa
new Vue()
绑定 ID - 3、通过服务端渲染,ajax 获取 纯 Html 进行 dom 操作嵌入到 body 中
我们在现有的项目改造中,通过 第 2 种方案,将 登录页面 进行改造过,适用于固定且稳定迭代次数少的页面,并且与企业页面耦合程度较轻适合使用
第 3 种方案的话,适用于纯 列表或 非动态脚本控制的页面,例如文章列表,评论列表等,豆瓣的部分列表采用的则是此方案
当然,以上 3 中方案都不适用于 需要 Seo 进行优化的页面
这里我们要解决的场景为 一个完成任务的页面,该任何模块与其他页面 基本上 0 耦合,也只收集页面数据。其中的 iframe 只用于 写数据,客户端用于读数据。并不会和服务数据有过多交集。
且 iframe 端,需要在多处进行使用
window.postMessage
window.postMessage() 方法可以安全地实现跨源通信。意思则为:在两端,客户端 和 嵌入 iframe
端可以进行相互通信
首先,我们在这里定义一套描述
引入 iframe
端 叫: 客户端
被引入 iframe
端 叫: 被引端
按照常见的机制,我们针对 iframe 进行操纵时,我们可以直接通过 dom 阶段进行控制
<body>
<div class="container">
<iframe src="http://192.168.50.9:5500/iframe.html" frameborder="0"></iframe>
</div>
</body>
<script>
var iframe = document.querySelector('iframe');
iframe.document.body.style.backgroundColor = 'red';
....
但是,安全机制层面来讲,官方描述为
对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为 https),端口号(443 为 https 的默认值),以及主机 (两个页面的模数 Document.domain 设置为相同的值) 时,这两个脚本才能相互通信。
但是这里的话,我们可以 window.postMessage 来规避此问题
这里列出几个核心方法
- 发送数据
<iframe src="http://192.168.50.9:5500/iframe.html" frameborder="0"></iframe>
<script>
document.querySelector('iframe').iframe.postMessage("我的消息", "*")
</script>
- 接受数据
<script>
window.addEventListener("message", (event) => {
console.log(event)
}, false);
</script>
- 安全限制
postMessage(message, origin)
<script>
document.querySelector('iframe').iframe.postMessage("我的消息", "https://developer.mozilla.org")
</script>
当 origin 设置 * 后,是允许任何人进行处理的,不会有跨域等相关问题。
查看 demo 演示
https://surest-sky.github.io/iframe/client.html
源代码
https://github.com/surest-sky/surest-sky.github.io/blob/master/iframe/client.html
本文由 邓尘锋 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Sep 1, 2022 at 10:58 am