6

我正在尝试使用 chrome 扩展访问本地 var。在页面脚本中尝试console.info(myVar)时,我得到myVar is not defined

但是,当使用 chrome 开发人员工具并在调试控制台中执行相同的代码段时,我得到了 myVar 的全部内容。

尝试访问时的行为相同window.myVar,这只是undefined通过 chrome 扩展打印时。

通过开发工具和页面脚本使用以下代码段将脚本标签注入正文,会产生完全相同的行为。

   $("body").append($("<script />", {
      html: "console.info(myVar);"
   }));

在开发工具中执行时会打印变量,但在页面脚本中出现 javascript 错误

4

2 回答 2

5

你看到的是预期的行为。

内容脚本在称为孤立世界的特殊环境中执行。他们可以访问被注入页面的 DOM,但不能访问页面创建的任何 JavaScript 变量或函数。它查看每个内容脚本,就好像它正在运行的页面上没有执行其他 JavaScript。反过来也是如此:在页面上运行的 JavaScript 不能调用任何函数或访问由内容脚本定义的任何变量。

http://developer.chrome.com/extensions/content_scripts.html#execution-environment

当您console.info(myVar);从页面、Chrome 开发工具的控制台或注入的脚本运行时,它会在页面的上下文中运行,因此会看到定义的变量。

但是,当从扩展代码内部运行相同的代码时,您将在完全不同的环境中运行,因此myVar未定义。

您也许可以使用共享 DOM 来解决这个问题。
http://developer.chrome.com/extensions/content_scripts.html#host-page-communication

编辑

除非有人纠正我,否则console.info(myVar);下面的代码将被注入到script元素中,同时仍在扩展的上下文中执行:

$("<script />", {
    html: "console.info(myVar);" // myVar points to extension's myVar, not page's
});

一个简单的测试可以通过记录chrome.extension对象或myVar在内容脚本中声明来运行——这chrome.extension将是可用的,并且myVar将完全按照内容脚本中的定义进行记录。

建议是使用外部脚本(这对于模块化也更好),将其添加到web_accessible_resources并创建一个具有指向该外部脚本script的属性的元素。src

下面的示例扩展代码在加载启用扩展的 test.html 页面时会提醒“测试”。

清单.json

{
    "name": "Test",
    "version": "0.1.0",
    "manifest_version": 2,
    "description": "Just a test.",
    "content_scripts": [{
        "matches": ["<all_urls>"],
        "js": ["contentscript.js"]
    }],
    "web_accessible_resources": [
        "myscript.js"
    ]
}

test.html(被访问的页面)

<!DOCTYPE html>
<html>
<head>
    <script>
        window.test = 'test';
    </script>
</head>
<body>
</body>
</html>

内容脚本.js

var script = document.createElement('script');
script.type = 'text/javascript';
script.src = chrome.extension.getURL('myscript.js');
document.getElementsByTagName('head')[0].appendChild(script);

myscript.js(这是将在页面上下文中运行的外部脚本)

alert(window.test);
于 2013-05-28T06:25:10.923 回答
2

Oleg和我在一次聊天会话中找到了问题的根源。

我尝试使用以下代码段注入脚本:

   $("body").append($("<script />", {
      html: "console.info(myVar);"
   }));

正如Oleg在他的回答中所写,看起来该console.info部分在到达页面正文之前就已执行,从而导致在此处具有扩展上下文。非 jQuery 版本虽然可以正常工作:

var g = document.createElement('script'); 
var s = document.getElementsByTagName('script')[0]; 
g.text = "console.info(myVar);" 
s.parentNode.insertBefore(g, s);
于 2013-05-28T08:28:14.897 回答