将JS代码注入网站的所有页面

时间:2015-05-01 19:38:26

标签: javascript google-chrome-extension

我试图将JS代码注入网站,代码在其所有网页上执行。我发现这可以使用chrome内容脚本完成。因此,我做了以下事情:

  1. 我已创建" contentscript.js"。

    var x = []
    s.src = 'AN EXTERNAL JS FILE';
    (document.getElementsByTagName('head')[0] || document.body).appendChild(s);
    
  2. 我已经创建了" manifest.json"。

    {
       "name": "Sample",
       "version": "1.0",
       "manifest_version": 2,
       "permissions": [
           "tabs",
           "*://*/*"
       ],
       "icons": { "128":"logo.png" },
       "content_scripts": [{
           "js": ["contentscript.js"],
           "matches": ["<all_urls>"]
       }]
    }
    
  3. 两个文件都存在于同一个文件夹中。

  4. 我已将它们加载到Chrome扩展程序中。

  5. 脚本按预期执行。

  6. 我注入的脚本将外部JS文件加载到页面中,并在head标记下放置一个脚本元素。这个JS也使用我在注入的JS脚本中定义的x变量。但它无法读懂它的问题。在控制台中,它会抛出错误,x变量未定义。

    如何以外部JS文件可访问的方式定义变量,提到我既不能访问网站也不能访问外部JS文件?

    谢谢,

1 个答案:

答案 0 :(得分:2)

内容脚本位于an isolated world。您可以在页面上下文之外定义<script>,因此它在其中运行的脚本是不可见的。有关详细信息,请参阅this answer

但是,通过x标记添加脚本会将脚本放入页面的上下文中。因此,它没有看到变量。

您有3种可能的解决方案。

  1. 在页面的上下文中完全使用<script>。因此,您需要在script = document.createElement("script"); script.textContent = 'x = [];'; (document.getElementsByTagName('head')[0] || document.body).appendChild(script); 代码中定义它:

    x
  2. 让页面级脚本和内容脚本进行通信(例如,传递postMessage)。

    实现此目标的一种方法是通过custom DOM events。另一个是described in the docsSymfony profiler/toolbar)。最后,正如xwhyLikeThis所建议的那样,您可以将值存储在隐藏的DOM节点中。

  3. 在内容脚本上下文中加载外部脚本。这需要从后台脚本和XHR使用injecting it programmatically获取它。或者,如果您可以使用扩展名包含文件的静态版本 - 只需按照常规方式将其与内容脚本一起注入。

  4. 就个人而言,我建议2。