购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.3 基于iframe的微前端示例

自HTML4引入iframe标签以来,它便一直受到人们的广泛关注和讨论。iframe拥有一些独特且不可替代的优势,但同时也伴随着一些让人不禁摇头的问题。iframe为浏览器提供了一种嵌入内容的原生方式,利用了浏览器的多进程架构,实现了接近完美的隔离效果。然而,正是这种过度的隔离,使得在iframe之间进行通信变得复杂,往往需要采取一些非传统的方法。

尽管存在挑战,iframe在微前端架构中仍然是一个不可忽视的重要解决方案。它的原生特性所带来的优势是其他技术难以匹敌的。本节将通过一个实例来探讨如何利用iframe方案实现微前端架构的集成。通过这个例子,我们可以更加深入地理解iframe在微前端中的应用,以及如何巧妙地解决它带来的通信难题。

3.3.1 iframe方案核心

iframe的本质实际上类似于在页面中嵌入了一个独立的浏览器标签页。在第1章中,我们大致探讨了多进程浏览器的基本架构和历史演变,这有助于深入了解浏览器如何隔离不同域名的内容。这种“隔离”措施的根本目的在于提高安全性。正如第1章所述,早期的浏览器并非采用多进程架构,而是以单一进程处理所有任务,包括页面渲染、JavaScript解析以及浏览器插件等。这种设计意味着,一旦某个页面出现故障,整个浏览器都可能会崩溃。此外,不安全的第三方插件甚至有可能窃取用户的网络活动信息以及本地用户的个人数据。

iframe依赖于浏览器的原生功能,几乎不存在移植和复用的额外成本,只需在需要的地方嵌入即可,同时还具备出色的隔离性能。尽管如此,iframe并非没有缺点。它不能维护URL状态,无法根据父容器计算位置,也无法实现数据的持久化存储,这些问题成为许多有意采用iframe作为微应用架构的人士的顾虑。

然而,无论面临何种挑战,问题总有解决的方法。保持URL状态、实现父子组件间的通信,或是数据的持久化存储,都不是不可克服的难题。

3.3.2 浅谈iframe方案的适用场景

在日常开发工作中,相信读者都听说过“跨域”这个术语。它指的是浏览器出于隔离、安全及开放的考虑,限制不同域名网站间的数据访问和服务器交互。然而,除跨域外,浏览器安全领域还有另一个技术概念—“跨站”。跨站与跨域的区别在于:跨域是指当协议、域名或端口号中任意一项不同时,即构成跨域;而跨站则是指有效顶级域名(eTLD)加上一级域名不同的情况,即视为跨站。


    // 跨域
    https://www.zaking.com
    http://www.zaking.com
    // 跨站
    https://www.zaking.com
    http://a.zaking.com
    https//b.zaking.com:9090
    http://c.zaking.com:1000

通过上面的示例,读者可以明显地看出跨域与跨站的区别,只要是eTLD+1(即有效顶级域名)不同,就构成跨站;如果三要素之一不同,那就是跨域。

在实际的开发过程中,我们设想一个常见的场景:通常,我们会将其他项目嵌入自己的项目中,而这些被嵌入的项目部署在同一服务器上,或者至少可以使用相同的站点域名。这意味着,当我们打算利用iframe来构建微前端解决方案时,通常能够相对容易地实现同站或同域的条件。

当然,我们也可能遇到这样的情况:使用或嵌入来自第三方或其他服务提供商的项目。这类项目通常设计为可以独立部署,因此在这种情况下,跨站问题就不复存在了。

上述讨论都是基于较为理想的状况,它们为我们提供了相对“自由”的操作空间。然而,如果你试图在自己的项目中嵌入百度的页面,并期望与之进行数据交互,那么必须指出,这是不可行的。笔者曾在博客上用过一个类比:你可以随意进出自己的家,但想要擅自进入别人的家,显然是不被允许的。互联网世界亦是如此,即便你通过某些技术手段获得了访问他人资源的“钥匙”,这样的行为也等同于非法侵入。浏览器的设计初衷正是为了极力阻止这种通过技术手段侵犯他人隐私和安全的行为。

3.3.3 基于iframe实现微前端的小例子

前面介绍了iframe的一些基本概念,本小节将实现一个基于iframe嵌套的小例子。我们先来看一下目录结构,如图3-5所示。

图3-5 iframe示例目录结构

接下来,我们将展示最终的页面效果,如图3-6所示。

图3-6 iframe示例效果图

单击按钮,可以切换对应的iframe子项目。其中,第三个子项目嵌套了两个平级的三级子项目。核心代码如下:

代码很简单,且服务端代码与路由式微前端中的例子类似,因此不再赘述。以下是son3.html的代码:

读者可以在随书资源中查看完整的源代码。细心观察上述代码会发现,iframe加载的地址是本地的localhost。为了让这个例子更加贴近实际场景,我们将沿用前文提到的方法,通过配置本地的Nginx服务器和修改hosts文件来调整域名映射,使之更为贴近真实环境。核心Nginx配置代码如下:

然后,我们在hosts文件中增加以下配置:


    127.0.0.1 www.zakingwong2.com

这样,就可以像之前路由式微前端例子一样,在浏览器中使用自定义的域名了。当然,还需要修改iframe对应的地址,以下是修改后的father.html文件内容:


    son1Btn.addEventListener('click',()=>iframeContent.src='http://www.zaking
wong.com/son1')
son2Btn.addEventListener('click',()=>iframeContent.src='http://www.zakingwong
.com/son2')
    son3Btn.addEventListener('click',()=>iframeContent.src='http://www.zaking
wong.com/son3')

然后,再修改son3.html中引入的iframe路径:

在son3.html中,第一个iframe使用的是zakingwong的域名,第二个则使用zakingwong2域名。到此为止,大功告成,我们可以通过浏览器访问www.zakingwong.com来“真实”地测试这部分内容,以查看预期效果。

至此,本节讨论即将结束。在结束之前,笔者想留给读者一个思考:在刚才的例子中,笔者采用的是横向拆分方案还是纵向拆分方案?又或者,这两种方案是否在这个示例中同时应用了? tmwOQEE7HS4xF0k991hZlzMx7S+dWXWkSFkHDRDnERq4WjdlOnmFQ4c4qFsP0/Tm

点击中间区域
呼出菜单
上一章
目录
下一章
×