window.postMessage 解决 Vue 和 原生 html 混合开发的问题

in 前端 with 0 comment

window.postMessage 解决 Vue 和 原生 html 混合开发的问题

由于历史项目的问题,原生采用的是 jquery,我们无法显著和快速的针对某个模块进行开发。当然,Vue 的话可以快速的帮我们解决这个问题

常见的解决方案有几种

我们在现有的项目改造中,通过 第 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

Responses