Javascript Chrome扩展:创建选项卡,然后将内容脚本注入其中
在收到来自内容脚本的消息后,我想创建一个新的选项卡并填充它动态打开的页面(现在我只是尝试将新创建的页面变成红色) eventPage.js:Javascript Chrome扩展:创建选项卡,然后将内容脚本注入其中,javascript,google-chrome-extension,Javascript,Google Chrome Extension,在收到来自内容脚本的消息后,我想创建一个新的选项卡并填充它动态打开的页面(现在我只是尝试将新创建的页面变成红色) eventPage.js: // ... code that injects another content script, works fine // Problem code... chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) { chrome.tab
// ... code that injects another content script, works fine
// Problem code...
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse)
{
chrome.tabs.create({url: chrome.extension.getURL("blankpage.html")},
turnTabRed);
});
function turnTabRed(tab)
{
chrome.tabs.executeScript(
tab.id,
{code: 'document.body.style.backgroundColor="red"'}
);
}
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse)
{
chrome.tabs.create({url: chrome.extension.getURL("blankpage.html")}, turnTabRed);
});
function turnTabRed(tab)
{
chrome.tabs.sendMessage(tab.id, {"action" : "setBackground"});
}
这将成功创建一个新选项卡并加载blankpage.html
(这只是一个带有一些文本的html页面),但无法将背景颜色涂成红色。在不同位置插入console.log()
语句并在调试器中闲逛之后,我确定正在调用turnTabRed
,tab.id
确实是新创建的选项卡的id,如果我从控制台调用document.body.style.backgroundColor=“red”
,新选项卡的背景变为红色。我注意到如果我加上
(*)
在turnTabRed
的主体中,新选项卡的标题不会打印到控制台中,这表明脚本被注入得太早,因此我尝试使用setTimeout
延迟注入,但失败后,我尝试侦听status complete事件:
function turnTabRed(tab)
{
chrome.tabs.onUpdated.addListener(
function(tabUpdatedId, changeInfo, tabUpdated)
{
if (tabUpdatedId == tab.id && changeInfo.status &&
changeInfo.status == 'complete')
chrome.tabs.executeScript(
tabUpdatedId,
{code: 'document.body.style.backgroundColor="red"'});
});
}
这也失败了。使用setTimeout
等待后调用(*)确实打印了新选项卡的标题以及所有其他标签
怎么了?如何创建一个新选项卡,加载一个HTML页面,然后将其背景变成红色?问题是您无法将脚本插入
chrome扩展://*
页面(您的blankpage.HTML
就是这样的页面)
例如,改变
{url: chrome.extension.getURL("blankpage.html")}
到
在原始代码块中,它会将背景更改为红色。据我所知,没有办法注入chrome扩展://*
页面(我认为这是一个巨大的安全问题)。我不知道你的扩展试图做什么,但是注入到一个“实时”页面应该可以工作…也许你可以创建一些API来在你的服务器上生成一个新的“空白页面”,只要chrome.runtime.onMessage.addListener
触发
编辑
因此,您不能将内容注入chrome extension://*
页面,但您可以将消息传递给它们,并在这些新页面中使用chrome API的某些子集,如下所述。因此,使用消息传递,您将能够准确地执行您想要的操作(修改新页面),尽管是以迂回的方式。下面是一个对我来说非常简单的概念证明:
eventPage.js:
// ... code that injects another content script, works fine
// Problem code...
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse)
{
chrome.tabs.create({url: chrome.extension.getURL("blankpage.html")},
turnTabRed);
});
function turnTabRed(tab)
{
chrome.tabs.executeScript(
tab.id,
{code: 'document.body.style.backgroundColor="red"'}
);
}
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse)
{
chrome.tabs.create({url: chrome.extension.getURL("blankpage.html")}, turnTabRed);
});
function turnTabRed(tab)
{
chrome.tabs.sendMessage(tab.id, {"action" : "setBackground"});
}
blankpage.js:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if(request.action == "setBackground") document.body.style.background = "red";
});
在控制台中运行
chrome.extension.getURL(“blankpage.html”)
将返回chrome-extension:///blankpage.html
(非chrome://...
)并使用chrome extension://*/*
作为示例模式;但是,如果我将该模式放在清单中的权限下
chrome会发出警告:“权限'chrome extension://*/*'未知或URL模式格式不正确”。将其置于content\u scripts
的matches
属性下也会在加载扩展时产生错误。你能指出一些说明这一点的文档吗?我仍然无法注入blankpage.html
,但我可以将blankpage.js
(html页面的JavaScript)中的消息传递到扩展页面,以便使用chrome.runtime.sendmages()动态修改blankpage.html
(这是我最初的目标)
,例如:chrome.runtime.sendMessage({},函数(响应){document.body.style.backgroundcolor=“red”;})代码>。如果你修改你的答案,让它作为一种解决办法,我很乐意接受。啊,有趣的是,blankpage.js
是从blankpage.html
的html链接而来的javascript文件吗?还是内容脚本?如果您能够将内容脚本注入chrome://*
页面,那么在选项卡创建的回调中向新页面的内容脚本传递消息可能是一个可行的解决方案?这是一个非常有趣的问题。。。如果有机会,我会研究更多的解决方案:)。对不起,我不清楚,blankpage.js
是从blankpage.html
的html链接而来的。从包含在扩展中的html页面(而不是事件/背景页面或内容脚本的一部分)链接的javascript似乎可以访问chrome.*
API的某个子集-至少它可以调用chrome.runtime.sendMessage()
。这就足够了——从html页面链接的javascript可以负责在消息中显示从事件页面传递的数据。我仍然无法自动或以编程方式注入到页面中-请参阅我的第一条评论。我已经用一些适合我的新代码更新了答案。