读取shadow-root(closed)里面的内容

读取shadow-root(closed)里面的内容

问题描述

在一次查看网页的内容时,发现有的内容没有办法解析出来,而我要的元素就隐藏在shadow-root(closed)中。而我知道只有shadow-root(open)中的元素才是可以访问的。于是开始在网上查找相关内容。

官网介绍

而在官网中,作者介绍的一句话让我印象深刻:如果一个关闭的影子根和打开的影子根一样可以访问并获取的话,那为什么还需要一个关闭的影子根呢?

同时在官网中还存在唯一的解决方式,就是通过重载shadow-root(closed)成shadow-root(open)。

测试过程

尝试在网页中将元素通过这种方式重新加载,但是似乎并没有起任何作用,同时也在一些有影子根的网站中测试过了,然而依旧没有起作用。网上一番求药,基本都是用js语句获取打开的shadow-root(open)的教程,最后终于在stark-overflow上找到了唯一的解决方案(坑很多,Google上基本有shadow-root(closed)的博客都看过了)。同样也是将shadow-root(closed)转成shadow-root(open)状态。至于怎么从open状态下取数据,可以自行百度,相关解决方案有很多。

解决方案

思路就是将closed改成open状态,然后再从中通过js访问数据。但是既然在浏览器的控制台中没有办法让它实现,那我们就在程序加载之前将影子根打开。

这里我贴上三个文件的代码。写完后只需要在Google浏览器的开发者模式中加载解压好的拓展程序(带有这三个文件的文件夹)就可以了。就像平时自己下载的插件一样。
injected.js

Element.prototype._attachShadow = Element.prototype.attachShadow;
Element.prototype.attachShadow = function () {
    console.log('attachShadow');
    return this._attachShadow( { mode: "open" } );
};

manifest.json

{
“name”: “SeleniumTesting”,
“description”: “将网页上的shadow-root(closed)重载成shadow-root(open)”,
“version”: “1.0”,
“author”: “Author”,
“manifest_version”: 2,
“permissions”: ["<all_urls>", “https://www.baidu.com/"],
“content_scripts”: [{
“matches”: ["https://你需要让它生效的网站.com/
”],
“run_at”: “document_start”,
“all_frames”: true,
“js”: [“shadowInject.js”]
}],
“web_accessible_resources”: [“injected.js”]
}

shadowInject.js

const injectedScript = document.createElement('script');
injectedScript.src = chrome.extension.getURL('injected.js');
(document.head || document.documentElement).appendChild(injectedScript);

全程只需要在第二个网站中修改你需要让它生效的网站域名即可。

如果说看不懂这三个文件,有兴趣的话可以百度看一下这三个文件的书写规则,以及每个文件内参数代表的内容。

最后看一下修改前和修改后的对比图:
before
在这里插入图片描述
after
在这里插入图片描述
插件:
在这里插入图片描述

### Shadow Root 的概念 Shadow Root 是 Web 组件中的一个重要组成部分,它允许开发者在一个独立的作用域内创建和管理 HTML 结构、样式以及行为。这种作用域上的隔离意味着在 Shadow DOM 中定义的内容不会受到文档其他部分的影响,反之亦然[^1]。 具体来说,Shadow Root 提供了一种机制来封装节点树,使其与主文档流分离。这意味着可以在不干扰全局样式的前提下应用特定于该组件的 CSS 样式;也可以保护内部结构免受外部 JavaScript 操作的影响。此外,通过设置 `mode` 属性为 `'open'` 或者 `'closed'` 可以控制是否允许外界访问这个影子根下的内容[^3]。 ### 创建并使用 Shadow Root 为了利用 Shadow Root 构建自定义元素,通常会在类构造器中调用 `attachShadow()` 方法,并指定要附加的目标元素作为上下文对象 (`this`) 。此方法接收一个配置选项的对象参数,其中最重要的属性是 `mode` ,用于决定新创建出来的 Shadow Root 是否对外开放读取权限: - 当 `mode='open'` 时,可以通过 `.shadowRoot` 获取到对应的实例; - 如果设定了 `mode='closed'` 则不允许任何方式获取其引用[^2]。 下面是一个简单的例子展示如何初始化带有封闭型 (closed) 影子 DOM 的自定义元素: ```javascript class MyCustomElement extends HTMLElement { constructor() { super(); // 初始化 shadow root 并设定模式为 closed const shadowroot = this.attachShadow({ mode: 'closed' }); // 向 shadow dom 添加一些基本内容 let templateContent = document.createElement('template'); templateContent.innerHTML = ` <style> p { color: blue; } </style> <p>Hello from the other side!</p>`; shadowroot.appendChild(templateContent.content.cloneNode(true)); } connectedCallback(){ console.log('MyCustomElement has been added to page.'); } } // 定义新的自定义标签名及其关联的类 customElements.define('my-custom-element', MyCustomElement); ``` 在这个案例里,即使页面上有其他的脚本尝试操作 `<my-custom-element>` 下面的内容,由于采用了关闭状态(`closed`)Shadow Root 设计,这些尝试都将失败,从而实现了良好的安全性和模块间解耦合效果。
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值