所以在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 和更改背景颜色之类的基本内容时,它工作得很好,但似乎不适用于我尝试使用的预制脚本。就像我在上一篇文章中提到的那样,当我将脚本粘贴到控制台中时,我的脚本就可以很好地工作 - 我希望扩展程序能够做到这一点。 当我说脚本不依赖于页面上的任何内容时,我一开始可能是错的。
通过控制台运行代码时到底发生了什么,以及如何通过扩展运行相同的代码?
谢谢。
最佳答案
您的代码在控制台和内容脚本中的工作方式不同,因为 Chrome 会创建一个单独的 isolated JavaScript context对于每个扩展的脚本。
造成这种情况的原因有很多,尤其是安全性:该页面不能影响在更高权限的扩展上下文中运行的脚本。此外,这意味着页面使用的代码和脚本之间不存在冲突。有关更多信息,请参阅上面的链接。
<小时/>当您在控制台中执行代码时,您可以注意到控制台上方有一个下拉菜单,默认情况下显示 <top frame>
。您可以在此处选择要在其中执行命令的上下文。如果有从任何扩展注入(inject)的上下文脚本,您也会在那里看到其上下文。
你提到的脚本是指页面上已经定义的JavaScript对象;这就是为什么如果您默认在控制台中执行它,它会起作用,但是当从上下文脚本调用时,这些对象不存在。
<小时/>那么,这些是完全孤立的吗?两个上下文都共享对 DOM 的访问。这使得内容脚本能够将代码注入(inject)到页面的上下文中:您可以创建 <script>
元素并将其插入到页面中。这将在页面上下文中执行代码。
有关涵盖此主题的规范问题,请参阅 Inject code in a page using a Content script 。官方文档中几乎没有提到这一点,坦率地说,当我第一次看到它的可能性时,我大吃一惊。
因此,就您而言,您需要一个充当代理的内容脚本,注入(inject)页面级脚本:
// 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" ],
关于javascript - 从弹出窗口中执行当前选项卡中的脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26036345/