有没有办法防止影子dom中的javascript访问它之外的DOM?

时间:2018-06-14 16:42:06

标签: javascript dom shadow-dom

所以,如果我有:

enter image description here

js可以更改component_test_div

中的文字

我可以阻止吗?

2 个答案:

答案 0 :(得分:0)

脚本不受shadow DOM

保护

Shadow DOM仅保护CSS泄漏或干扰shadowRoot的内容。它不会为JavaScript创建新的命名空间。

在这段代码中,我在阴影根中有一些JS:

class MyEl extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode:'open'});
    let s = document.createElement('script');
    s.textContent = "function dog() { console.log('Bark, Bark'); }";
    this.shadowRoot.appendChild(s);
  }
}

customElements.define('my-el', MyEl);

setTimeout(()=>dog(), 2000);
<my-el></my-el>

2秒后我们调用函数dog()并且它可以工作。这是因为,即使将此代码放入shadowRoot中,它仍然在全局范围内执行。

鉴于无法在Web组件中隔离您的JavaScript,您需要记住它在其范围内的任何人都可以使用。

如果您将代码放在IIFE中,那么您可以阻止外部调用。但是仍然无法阻止内部调用或操纵范围之外的内容。

确定您的元素是否在shadowDOM

中的替代方法

作为@Angel Politis的答案的替代方案,有一种更简单的方法来确定某个元素是否在某人的shadowRoot中:

function isInShadowDOM(el) {
  let ret = false;

  if (el.getRootNode) {
    doc = el.getRootNode();
    ret = (doc !== document);
  }

  return ret;
}

答案 1 :(得分:0)

您可以将关闭的Shadow DOM 用于您要保护的元素。

component_test_div.attachShadow( { mode: "closed" } )
                  .innerHTML = "READ-ONLY"
                  
app_list.attachShadow( { mode: "closed" } )
        .appendChild( script.content )
<div id="component_test_div"></div>

<div id="app_list"></div>

<template id="script">
    <script>
        console.info( "shadowRoot is", component_test_div.shadowRoot )
        component_test_div.textContent = "SHADOWED BY SHADOW DOM"
    </script>
</template>

影子根的内容将替换任何初始或更改的文本。 关闭属性将阻止其他脚本访问阴影根。

enter image description here