在弹出窗口中执行当前选项卡中的脚本

时间:2014-09-25 10:31:39

标签: javascript google-chrome google-chrome-extension

因此,在this thread接受良好教育并进一步开发Chrome扩展程序之后,似乎我需要更多关于如何向前发展的方向。

function testFunction() {
    chrome.tabs.query({active: true, currentWindow: true}, function(arrayOfTabs) {
    var activeTab = arrayOfTabs[0];
    chrome.tabs.executeScript(activeTab.id, {file: "test.js"});
});

test.js包含我的脚本。它在使用console.log和更改背景颜色等基本内容时可以正常工作,但似乎不适用于我试图使用的预制脚本。就像我在之前的帖子中提到的那样,当我将它简单地粘贴到控制台中时,我的脚本运行良好 - 我希望扩展能够做到这一点。 我起初可能是错的,因为我说脚本不依赖于页面上的任何内容。

通过控制台运行代码到底发生了什么,以及如何通过扩展程序运行相同的代码?

感谢。

1 个答案:

答案 0 :(得分:2)

您的代码在控制台和内容脚本中的工作方式不同,因为Chrome会为每个扩展程序的脚本创建一个单独的isolated JavaScript context

它有很多原因,尤其是安全性:页面不会影响在更高权限扩展上下文中运行的脚本。此外,这意味着页面使用的代码与脚本之间没有冲突。有关更多信息,请参阅上面的链接。


在控制台中执行代码时,您会注意到控制台上方的下拉列表,默认情况下会显示<top frame>。您可以在此处选择执行命令的上下文。如果从任何扩展中注入了上下文脚本,您也会在其中看到其上下文。

您提到的脚本是指已在页面上定义的JavaScript对象;这就是为什么它在默认情况下在控制台中执行它的原因,但是当从上下文脚本调用时,这些对象不存在。


那么,那些是完全孤立的吗?两个上下文都共享DOM访问权限。这使内容脚本能够将代码注入页面的上下文中:您可以创建<script>元素并将其插入页面。这将在页面的上下文中执行代码。

有关此主题的规范问题,请参阅Inject code in a page using a Content script。在官方文档中几乎没有提到这一点,并且在我第一次看到它可能时坦率地引起了我的注意。

因此,在您的情况下,您需要一个充当代理的内容脚本,注入页面级脚本:

// content.js - this is what you pass to `executeScript`
var s = document.createElement('script');
s.src = chrome.runtime.getURL('test.js'); // This is the actual script
s.onload = function() {
    this.parentNode.removeChild(this);
};
(document.head||document.documentElement).appendChild(s);

为此,您需要将test.js添加到web-accessible resources in the manifest(因为当您添加<script>代码时,网页本身会请求加载它:

  "web_accessible_resources" : [ "test.js" ],