为什么JavaScript注入中的脚本标记会从Google Chrome扩展中删除?

为什么JavaScript注入中的脚本标记会从Google Chrome扩展中删除?,javascript,google-chrome-extension,content-script,Javascript,Google Chrome Extension,Content Script,从 我已经阅读了有关Stack…(堆栈…)的所有主题,以及谷歌关于谷歌Chrome扩展和脚本注入的文档,但我不理解上述注入脚本代码中第5行的用途: this.parentNode.removeChild(this); 我知道,我可能需要一些JavaScript学习,但是如果在脚本执行后不删除它会发生什么?分机会崩溃吗?它只是为了干净的编码还是有特定的用途?解释 让我们逐行分析此内容脚本的作用: 创建元素: var s = document.createElement('script');

我已经阅读了有关Stack…(堆栈…)的所有主题,以及谷歌关于谷歌Chrome扩展和脚本注入的文档,但我不理解上述注入脚本代码中第5行的用途:

this.parentNode.removeChild(this); 
我知道,我可能需要一些JavaScript学习,但是如果在脚本执行后不删除它会发生什么?分机会崩溃吗?它只是为了干净的编码还是有特定的用途?

解释 让我们逐行分析此内容脚本的作用:

  • 创建
    元素:

    var s = document.createElement('script');
    
  • 只是一个评论

  • 使用
    chrome.extension.getURL()
    方法将
    src
    属性设置为脚本
    script.js
    (位于扩展文件夹中)的绝对URL,该方法将返回类似于
    “chrome”的内容-extension://abcdefghijklmnopqrstuvwxyz/script.js“

  • 设置以前创建的脚本的
    onload
    函数,脚本加载到页面后将调用该函数:

    s.onload = function() { ...
    
  • 技巧来了:在
    onload
    函数中的这行代码将在加载完成后从页面中删除脚本。因此,脚本将被注入、执行,当它完成工作时,它将被删除。
    this
    关键字表示函数的所有者,实际上是脚本本身,并执行以下操作:

    this.parentNode.removeChild(this);
    
    表示:“从其父元素中删除脚本”

  • 只需关闭
    onload
    功能

  • 这一行在页面内注入脚本。括号内的条件首先查找
    元素,如果找不到,则查找
    元素,这样做:

    (document.head||document.documentElement).appendChild(s);
    
    字面意思是:“如果
    元素存在,则将脚本附加到它,否则将其附加到
    元素”

  • TLDR此代码将脚本注入到页面的上下文中,使其运行,并在完成运行后将其从页面中删除

    为什么要删除脚本? 好吧,有一些很好的理由,尽管它不是必需的,如果不删除它,您的扩展也不会崩溃

  • 首先,从页面中删除脚本会使您担心页面将无法读取其内容:即使这不太可能发生,某些页面也可以插入扩展代码并对其进行操作

  • 第二,如果脚本非常大,删除代码可能会很有帮助,因为它可以降低页面加载时间和javadccript执行速度,还可以降低页面的“检查”过程,因为使用ChromeDevTools窗口打开一个大的脚本标记会减慢窗口本身的速度,如果需要太多CPU,甚至会导致Chrome崩溃


  • 我之前已经在对我的回答的评论中说明了删除
    标记的原因:

    有人问我为什么要使用
    script.parentNode.removeChild(脚本)删除脚本标记。我这样做的原因是因为我喜欢收拾我的烂摊子。在文档中插入内联脚本时,会立即执行该脚本,并且可以安全地删除
    标记

    前面的注释应用于方法2/3,其中代码是内联的。方法1使用一个外部脚本(
    ),它总是异步加载和执行。如果在插入脚本标记后立即删除节点,则异步脚本加载将中止,脚本将永远不会运行。为了避免这种情况,必须在
    onload
    事件处理程序中删除节点:

    s.onload = function() {
        this.parentNode.removeChild(this);
    };
    
    或者,更简短地说,使用以下方法:


    除了上面给出的其他原因外,如果生成的脚本标记在之后没有被移除,那么就不可能再次注入脚本。至少对Chrome来说是这样,我认为其他浏览器也是如此。

    我认为这确实是@RobW个人的问题。@Xan电子邮件会比an-ping更快。蜗牛邮件在这种情况下会更快(5个多月过去了)。@RobW可能是因为如果你没有触及这个问题,ping就不起作用了你已经解释了代码的作用。我想OP知道这一点。您没有解释原因。只有在重复使用
    标记时,才会出现这种情况。通常你会不断添加新的
    s,这很好用。不在Chrome(41版)中。我敢说,如果你改变URL,那么附加脚本就可以了,但这不是我要说的。浏览器将忽略重复的脚本标签是有意义的,因为通常返回的数据不会改变,浏览器会认为它是可缓存的。不能复制(41.0.227 2.77)。代码>var s=document.createElement('script');s、 src=chrome.runtime.getURL('s.js');document.body.appendChild(s.cloneNode());document.body.appendChild
    。实际上,外部脚本加载一次,但执行两次。
    (document.head||document.documentElement).appendChild(s);
    
    s.onload = function() {
        this.parentNode.removeChild(this);
    };
    
    s.onload = s.remove;