attachShadow样式隔离和JavaScript 沙箱

微服务样式隔离的原理是利用 Shadow DOM 技术来隔离各个微前端应用的样式。Shadow DOM 是 Web 标准的一部分,它允许将 DOM 树封装到一个隔离的影子 DOM 中,这样各个微前端应用的样式就不会相互影响,从而实现样式的隔离。
Qiankun 在每个微前端应用中使用 Shadow DOM 来包裹应用内部的 DOM 结构,以及应用所需的 CSS 样式。这样一来,即使各个微前端应用使用了相同的 CSS 类名,它们也不会相互影响,从而确保了样式的隔离。

dom的attachShadow创建影子节点,节点内和节点之外有什么关联吗?会互相影响?

attachShadow 方法创建的影子节点(shadow root)与宿主元素存在一定的关联,但是它们之间具有一定的隔离性,不会互相影响。

宿主元素(host element)是指通过 attachShadow 创建影子节点的元素,它拥有一个独立的影子节点。在影子节点内部定义的样式和元素,以及事件处理程序,都会局限在影子节点内部生效,不会泄漏到宿主元素所在的文档中。

具体来说,影子节点内的样式(CSS)不会影响到宿主元素,宿主元素的样式也不会影响影子节点内的元素。这意味着你可以在影子节点内定义特定的样式,而不用担心与外部样式的冲突。

同样,影子节点内的事件处理程序也是隔离的。在影子节点内注册的事件处理程序只会响应影子节点内的事件,不会响应宿主元素或其他元素的事件。这样可以确保影子节点内的事件逻辑不会影响到宿主元素及其周围的元素。

需要注意的是,影子节点内部的内容可以与宿主元素内部的内容进行交互。例如,在影子节点内部触发的事件可以通过事件冒泡机制传递到宿主元素或其他位于宿主元素之外的元素。但是,它们仍然保持了相对的独立性和隔离性。

通过使用 Shadow DOM 技术,我们可以将页面的功能和样式封装到独立的影子节点中,从而实现更好的代码组织和维护性,避免全局样式和事件的冲突,并改善模块化的开发体验。

Shadow DOM 技术原理,用代码去表达出来

当然可以!下面是一个更详细的代码示例,使用中文解释 Shadow DOM 技术的原理:

<!DOCTYPE html>
<html>
<head><style>/* 外部样式 */.container {border: 1px solid #ccc;padding: 10px;}</style>
</head>
<body><!-- 宿主元素 --><div id="host-element" class="container"><!-- 宿主元素内的内容 --><p>这是宿主元素内的文本。</p><button>点击我</button></div><script>// 获取宿主元素const hostElement = document.getElementById('host-element');// 创建影子根节点const shadowRoot = hostElement.attachShadow({ mode: 'open' });// 创建影子 DOM 的样式const styles = `/* 影子 DOM 样式 */.container {background-color: #f5f5f5;border: 1px solid #999;padding: 20px;}p {color: blue;}`;// 创建样式元素并将样式添加到影子根节点中const stylesElement = document.createElement('style');stylesElement.textContent = styles;shadowRoot.appendChild(stylesElement);// 创建影子 DOM 中的内容const shadowContent = document.createElement('div');shadowContent.textContent = '这是影子 DOM 内的文本。';shadowRoot.appendChild(shadowContent);// 在影子 DOM 中注册事件shadowContent.addEventListener('click', () => {console.log('点击了影子 DOM 内的内容');});// 将影子元素添加到影子根节点中shadowRoot.appendChild(shadowElement);</script>
</body>
</html>

在这个示例中,我们有一个 HTML 文档,其中包含了一个宿主元素(<div id="host-element">),宿主元素内有一些文本内容和一个按钮。

通过 JavaScript,我们首先获取了宿主元素,并使用 attachShadow 方法为它创建了一个影子根节点(shadow root),并指定 mode: 'open' 以允许外部访问影子 DOM。这样宿主元素就有了一个独立的影子 DOM。

接下来,我们创建了影子 DOM 的样式,定义在影子 DOM 内有效的 CSS 样式。我们通过创建一个样式元素,并设置其 textContent 为样式字符串,然后将样式元素添加到影子根节点中。这样,宿主元素内的样式不会影响到影子 DOM,而影子 DOM 内的样式也不会影响到宿主元素以及其他部分的样式。

然后,我们创建了影子 DOM 内的内容,这个例子中是一个 div 元素,内容为 “这是影子 DOM 内的文本。”。我们将内容元素添加到影子根节点中,这样影子 DOM 内的内容就与宿主元素内的内容进行了分离。

最后,我们在影子 DOM 中注册了一个点击事件的监听器,并打印了相关信息。这样,当点击影子 DOM 内的内容时,我们就会在控制台中看到相应的日志信息。这展示了影子 DOM 的事件隔离性,影子 DOM 内的事件不会影响到宿主元素以及其他部分。

通过 Shadow DOM 技术,我们可以实现样式和内容的封装、隔离和作用域限制,使得宿主元素和影子 DOM 内的元素可以独立开发和维护,相互之间不会产生冲突或干扰。

Shadow DOM 技术来隔离各个微前端应用的样式,进一步介绍Shadow DOM 技术底层原理

Shadow DOM 技术是 Web 标准中一种用于创建封装的、独立的 DOM 子树的技术。它的设计目的是为了将组件的样式、结构和行为封装起来,从而避免全局 CSS 样式或 JavaScript 代码的影响,特别适用于组件化开发和构建复杂的 Web 应用程序。

Shadow DOM 技术的底层原理:

  1. Shadow DOM 树:在使用 Shadow DOM 技术时,一个元素可以拥有一个或多个 Shadow DOM 树(shadow tree),每个 Shadow DOM 树是一个完全隔离的 DOM 子树。在 Shadow DOM 树中,可以包含自己的 HTML 结构、CSS 样式和 JavaScript 逻辑,与外部 DOM 结构相互独立。

  2. Shadow Host:拥有 Shadow DOM 的元素是其所属的 Shadow DOM 树的宿主元素,称为 Shadow Host。Shadow Host 可以是普通的 HTML 元素,也可以是自定义的 Web 组件。

  3. Shadow Root:每个 Shadow Host 对应一个 Shadow Root,它是 Shadow DOM 树的根节点,包含了该树的全部内容,包括 HTML 结构、CSS 样式和 JavaScript 逻辑。

  4. 封闭性:通过 Shadow DOM 技术创建的 Shadow DOM 树是封闭的,意味着它的内部内容对外部是不可见的。这意味着样式和脚本不会泄露或影响 Shadow DOM 外部的文档。

  5. 作用域 CSS:Shadow DOM 中的样式表会默认地被封装在 Shadow DOM 内部,这样它们不会影响到外部文档或其他 Shadow DOM 中的元素。这意味着即使使用全局选择器,也难以破坏 Shadow DOM 的封装性。

通过 Shadow DOM 技术,开发者可以创建独立的、封闭的 DOM 子树,每棵树都有自己的作用域和样式隔离,从而可以更好地构建大型 Web 应用中的组件化结构,并解决全局样式和脚本的污染问题。这种技术非常适合于构建现代的 Web 应用,特别是在微前端架构中实现独立应用的样式和行为隔离。

JavaScript 沙箱

JavaScript 沙箱的原理是通过使用浏览器的 JavaScript 的隔离机制来隔离各个微前端应用的 JavaScript 代码。Qiankun 利用了浏览器提供的 iframe 标签,将各个微前端应用作为独立的 iframe 加载到主应用中。每个 iframe 都有自己独立的 JavaScript 执行环境,因此它们之间的 JavaScript 代码是相互隔离的。

此外,在配合使用沙箱工具(如 openKyle 的 single-spa 库)时,Qiankun 还能对微前端应用中的一些敏感 DOM 操作进行拦截,通过代理机制和特定的沙箱环境来限制微前端应用对主应用的影响,从而保证了微前端应用之间的安全隔离。

综合来看,Qiankun 借助 Shadow DOM 和 iframe 技术,以及相关的沙箱工具,实现了微服务样式隔离和 JavaScript 沙箱的功能,确保了各个微前端应用在样式和 JavaScript 代码上的相互隔离,从而使得多个微前端应用可以安全、独立地运行在同一个页面上。

qiankun 微服务的 JS 沙箱,是指 qiankun 在每个子应用之间搭建的一种隔离机制,使用该机制可以构建一个安全的 JavaScript 运行环境,防止应用之间的相互干扰和污染。

该机制的实现原理,是通过将各个子应用中的 JS 代码加以隔离,使用 iframe 创建子应用,并在 iframe 中启动应用的 JS 代码,使每个子应用之间的 JS 运行环境互相隔离。这种嵌套式的运行环境,像是每个子应用都运行在自己的“沙箱”中一样,避免了子应用之间的干扰和污染。

在实现上,qiankun 通过封装一个 proxy 对象,将子应用中通过 window 对象访问全局变量的方式进行拦截,并将其映射到子应用自己的沙箱运行环境中。这样,即使不同子应用中使用了相同的全局变量名,也不会产生冲突,保证子应用之间的隔离性。

下面是一个简单的示例,展示了如何在子应用中访问全局变量和局部变量,并进行拦截和映射:

// proxy 对象对外暴露了一个 get 方法,用于拦截对象的属性访问
const sandboxProxy = new Proxy(window, {get(target, key) {// 如果访问的是全局变量,将其映射到当前子应用的沙箱环境,避免与其他子应用冲突if (key in target) {return Reflect.get(target, key);}// 如果访问的是局部变量,则返回当前子应用自己的变量return Reflect.get(自己的变量, key);}
});// 创建一个 iframe,并将其设置为子应用的沙箱环境
const appContainer = document.createElement('iframe');
appContainer.src = 'http://localhost:8080'; // 子应用的入口地址
appContainer.sandbox = 'allow-scripts'; // 允许执行 JS 脚本,但不允许访问同源策略外的内容
appContainer.contentWindow = sandboxProxy; // 使用自定义的 proxy 对象作为 window 对象
document.body.appendChild(appContainer);

通过使用 qiankun 微服务的 JS 沙箱,我们可以在微前端架构中实现各个子应用之间的隔离和安全性,提高应用的可维护性和可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/597427.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【重点】【BFS】542.01矩阵

题目 法1&#xff1a;经典BFS 下图中就展示了我们方法&#xff1a; class Solution {public int[][] updateMatrix(int[][] mat) {int m mat.length, n mat[0].length;int[][] dist new int[m][n];boolean[][] used new boolean[m][n];Queue<int[]> queue new Li…

软件工具集合

代码文档自动生成工具&#xff1a; Doxygen download 软件分析工具&#xff1a; perf gdb flamegraph 代码量统计&#xff1a; vscode插件&#xff1a;VS Code Counter 代码备注 vsocde插件&#xff1a; Line Note

Spring Boot 3 集成 Thymeleaf

在现代的Web开发中&#xff0c;构建灵活、动态的用户界面是至关重要的。Spring Boot和Thymeleaf的结合为开发者提供了一种简单而强大的方式来创建动态的Web应用。本文将介绍如何在Spring Boot项目中集成Thymeleaf&#xff0c;并展示一些基本的使用方法。 什么是Thymeleaf&#…

未来已来,Ai原生应用与人高度结合!学习就在现在?

原生应用&#xff1a;OpenAI™ChatGPT、Baidu.Inc™文心一言 也可以体验CSDN的INSCODE AI&#xff0c;集成多个国内GPT内容。 文章目录 前言----编程语言的未来&#xff1f;一、编程语言的教育1.1 学校所见所闻1.2 开启我们的Ai行程~io&#xff01;1.3 Ai结果评论 二、Ai编程教…

信息学奥赛一本通-编程启蒙3295:【例50.1】陶陶摘苹果

3295&#xff1a;【例50.1】陶陶摘苹果 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 2838 通过数: 1922 【题目描述】 陶陶家的院子里有一棵苹果树&#xff0c;每到秋天树上就会结出1010个苹果。苹果成熟的时候&#xff0c;陶陶就会跑去摘苹果。陶陶有个3030厘…

Linux环境vscode clang-format格式化:vscode clang format command is not available

问题现象 vscode安装了clang-format插件&#xff0c;但是使用就报错 问题原因 设置中配置的clang-format插件工具路径不正确。 解决方案 确认本地安装了clang-format工具&#xff1a;终端输入clang-format&#xff08;也可能是clang-format-13等版本&#xff0c;建议tab自…

[NISACTF 2022]popchains

[NISACTF 2022]popchains wp 题目代码&#xff1a; Happy New Year~ MAKE A WISH <?phpecho Happy New Year~ MAKE A WISH<br>;if(isset($_GET[wish])){unserialize($_GET[wish]); } else{$anew Road_is_Long;highlight_file(__FILE__); } /**********************…

AI实景无人直播创业项目:开启自动直播新时代,一部手机即可实现增长

在当今社会&#xff0c;直播已经成为了人们日常生活中不可或缺的一部分。无论是商家推广产品、明星互动粉丝还是普通人分享生活&#xff0c;直播已经渗透到了各行各业。然而&#xff0c;传统直播方式存在着一些不足之处&#xff0c;如需现场主持人操作、高昂的费用等。近年来&a…

Android Studio 报错Failed to find Build Tools revision 28.0.3

目录 前言 一、报错信息 二、报错原因 三、解决方案 四、更多资源 前言 当Android Studio报错提示"Failed to find Build Tools revision 28.0.3"时&#xff0c;通常意味着您的项目需要使用28.0.3版本的构建工具&#xff0c;但系统中并没有找到对应的版本。这可…

西电期末1020.寻找同数

一.题目 二.分析与思路 其实就是寻找字串的个数&#xff0c;以前好像是有类似的题&#xff0c;先找到子串的首字符&#xff0c;再判断 三.代码实现 #include<bits/stdc.h>//万能头 bool f(char* s,char* sub,int i,int l){for(int j0;j<l;j){if(s[ji]!sub[j])retu…

计算机组成原理复习

一、计算机系统概论 计算机由硬件和软件两大部分组成 软件分系统软件和应用软件翻译程序有两种&#xff1a;编译程序和解释程序冯诺依曼计算机的特点&#xff1a; 计算机由运算器、存储器、控制器、输入设备和输出设备五大部分组成。指令和数据以同等地位存放于存储器内&#…

如何成为ChatGPT 优质Prompt创作者

如何提问&#xff1f; 我想让你成为我的Prompt创作者。你的目标是帮助我创作最佳的Prompt&#xff0c;这个Prompt将由你ChatGPT使用。你将遵循 以下过程&#xff1a;1.首先&#xff0c;你会问我Prompt是关于什么&#xff1f;我会告诉你&#xff0c;但我们需要 通过不断的重复来…

labelme 标注的数据集转化为Mask-Rcnn适用的数据集

labelme 标注的数据集转化为Mask-Rcnn适用的数据集 食用步骤 1.labelme标注数据时&#xff0c;将生成的json文件和原图保存在一起 2.只需提供labelme生成的数据的文件夹&#xff0c;和maskrcnn的数据集文件夹&#xff0c;运行代码就会自动进行处理 3.代码会在提供的maskrcn…

brew 安装使用 mysql、redis、mongodb

在 Mac 生态中 brew 真是个万能神器&#xff0c;今天就来介绍一下怎么使用 brew 安装 mysql、redis、mongodb&#xff0c;以及如何使用 brew 启动、关闭、重启这些服务。 前言 brew 常用命令 # 查看brew的版本 brew -v# 更新homebrew自己&#xff0c;把所有的Formula目录更新…

索引类型-哈希索引

一. 前言 前面我们简单介绍了数据库的B-Tree索引&#xff0c;下面我们介绍另一种索引类型-哈希索引。 二. 哈希索引的简介 哈希索引(hash index) 基于哈希表实现&#xff0c;只有精确匹配索引所有列的查询才有效。对于每一行数据&#xff0c;存储引擎都会对所有索引列计算一个…

安卓11通过脚本修改相应板型系统属性

安卓10以后rk的一套源码兼容很多板型&#xff0c;多种cpu型号都兼容了&#xff0c;这一点相比之前省心了很多&#xff0c;所以就诞生了需要一套代码兼容多种板子的需求&#xff0c;定制修改中需要经常修改系统属性&#xff0c;通过以下脚本一次实现&#xff1a; #!/bin/bashfu…

华为 1+X《网络系统建设与运维(初级)》 认证实验上机模拟试题

华为 1X《网络系统建设与运维&#xff08;初级&#xff09;》认证实验上机模拟试题 一、考试背景二、考试说明2.1考试分数说明2.2考试要求2.3考试环境介绍2.4启动考试环境2.5保存答案 三、考试正文3.1考试内容3.1.1任务 1&#xff1a;设备连接3.1.2任务 2&#xff1a;设备命名3…

IDEA UML图

这个帖子介绍IDEA UML图 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 今天看landmark代码&#xff0c;然后想看一下UML图&#xff0c;这边整理一下相关知识点。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考…

Centos7静态网络配置

在vmware中打开&#xff0c; 点击虚拟网络编辑器&#xff0c;修改以下配置 网关IP最后一位固定为2&#xff0c;这个160根据下图中vmnet8的ip地址来的 打开网络控制面板>打开vmnet8查看 接着打开linux&#xff0c;有桌面版的使用桌面版更加方便 箭头这么乱&#xff0c;但是你…