简体   繁体   English

Chrome扩展程序:创建标签然后将内容脚本注入其中

[英]Chrome extension: create tab then inject content script into it

Upon receiving a message from a content script I want to create a new tab and fill the page it opens dynamically (for now I'm just trying to turn the newly created page red). 收到来自内容脚本的消息后,我想创建一个新选项卡并填充它动态打开的页面(现在我只是试图将新创建的页面变为红色)。

eventPage.js: 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"'}
  );
}

This successfully creates a new tab and loads blankpage.html (which is just an HTML page with some text) fine, but fails to paint the background colour red. 这会成功创建一个新选项卡并加载blankpage.html (这只是一个带有一些文本的HTML页面)很好,但无法将背景颜色绘制为红色。 After inserting console.log() statements in various places and fooling around in the debugger, I have ascertained that turnTabRed is being called, tab.id is indeed the ID of the newly created tab and if I call document.body.style.backgroundColor="red" from the console, the background of the new tab turns red. 在各个地方插入console.log()语句并在调试器中turnTabRed ,我已经确定正在调用tab.idtab.id确实是新创建的选项卡的ID,如果我调用document.body.style.backgroundColor="red"从控制台,新选项卡的背景变为红色。 I noticed that if I added 我注意到,如果我加入

(*) (*)

chrome.tabs.query(
    {}, function (tabArr) { for (var i = 0; tabArr[i]; i++)    
                              console.log(tabArr[i].title); });

into the body of turnTabRed the title of the new tab would not be printed into the console, which suggested that the script was being injected too early, so I tried delaying the injection with setTimeout and when that failed, I tried listening for the status-complete event: 进入turnTabRed的主体新标签的标题将不会打印到控制台,这表明脚本被过早注入,所以我尝试使用setTimeout延迟注入,当失败时,我试着听取状态 -完成活动:

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"'});
    });
}

which also failed. 这也失败了。 Calling (*) after waiting with setTimeout did print the new tab's title along with all the others though. 在使用setTimeout等待之后调用(*)确实打印了新选项卡的标题以及所有其他标题。

What's wrong? 怎么了? How can I create a new tab, load an HTML page and then turn its background red? 如何创建新选项卡,加载HTML页面然后将其背景变为红色?

The problem is that you cannot inject scripts into chrome-extension://* pages (which your blankpage.html is). 问题是你不能将脚本注入chrome-extension://*页面(你的blankpage.html是)。

For example, change 例如,改变

{url: chrome.extension.getURL("blankpage.html")} 

to

{url: "http://www.google.com"}

in your original codeblock and it will change the background to red. 在原始代码块中,它会将背景更改为红色。 As far as I know there is no way around injecting into chrome-extension://* pages (I would assume the reason for this is that it is a giant security concern). 据我所知,没有办法注入chrome-extension://*页面(我认为这是因为它是一个巨大的安全问题)。 I'm not sure what your extension is trying to do, but injecting into a "live" page should work...maybe you can create some API to generate a new "blankpage" on your server whenever the chrome.runtime.onMessage.addListener fires? 我不确定你的扩展程序试图做什么,但注入“实时”页面应该可以工作......也许你可以创建一些API,以便在chrome.runtime.onMessage时在你的服务器上生成一个新的“blankpage” chrome.runtime.onMessage.addListener会激活吗?

EDIT 编辑

So you can't inject stuff into chrome-extension://* pages, but you can pass messages to them and use some subset of chrome API's inside those new pages as mentioned below. 因此,您无法内容注入chrome-extension://*页面,但您可以将消息传递给它们,并在这些新页面中使用chrome API的一些子集,如下所述。 So using message passing you will be able to do exactly what you want (modify the new page), albeit in a roundabout way. 因此,使用消息传递,您将能够完全按照自己的意愿(修改新页面),尽管是以迂回的方式。 Here is a really simple proof of concept that works for me: 这是一个非常简单的概念证明,对我有用:

eventPage.js: eventPage.js:

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: blankpage.js:

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    if(request.action == "setBackground") document.body.style.background = "red";
  });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM