Chrome扩展程序:创建选项卡,然后将内容脚本注入到它 [英] Chrome extension: create tab then inject content script into it

查看:1171
本文介绍了Chrome扩展程序:创建选项卡,然后将内容脚本注入到它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在收到来自内容脚本的消息时,我想创建一个新标签并填充它动态打开的页面(现在我只是试图将新创建的页面变为红色)。



eventPage.js:

  // ...注入另一个内容脚本的代码,正常工作

//问题代码...
chrome.runtime.onMessage.addListener(
函数(request,sender,sendResponse)
{
chrome.tabs .create({url:chrome.extension.getURL(blankpage.html)},
turnTabRed);
});

函数turnTabRed(标签)
{
chrome.tabs.executeScript(
tab.id,
{code:'document.body.style。 backgroundColor =red'}
);
}

成功创建一个新选项卡并加载空白页。 html (这只是一个带有一些文本的HTML页面)很好,但是无法将背景颜色绘制为红色。在调试器中插入 console.log()语句并在调试器中混淆后,我确定 turnTabRed 是被调用时, tab.id 确实是新创建的标签的ID,如果我调用 document.body.style.backgroundColor =red,新选项卡的背景变成红色。我注意到,如果我添加了



(*)

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

放入正文 turnTabRed 的标题新选项卡不会被打印到控制台,这表明脚本被注入太早,所以我尝试用 setTimeout 延迟注入,当失败时,我尝试了监听状态完成事件:

  function turnTabRed(tab)
{
chrome.tabs。 onUpdated.addListener(
函数(tabUpdatedId,changeInfo,tabUpdated)
{
if(tabUpdatedId == tab.id&& $ ChangeInfo.status&& $ amp;
changeInfo。状态=='完成')
chrome.tabs.executeScript(
tabUpdatedId,
{code:'document.body.style.backgroundColor =red'});
});
}

其中也失败了。在等待 setTimeout 之后调用(*)确实会打印新标签的标题以及所有其他标题。



什么是错误?如何创建一个新标签,加载一个HTML页面,然后将其背景变成红色?

解决方案

问题是,你不能将脚本注入到 chrome-extension:// * 页面(您的 blankpage.html 是)。



例如,更改

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

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



在您的原始代码块中,它会将背景更改为红色。据我所知,没有办法注入 chrome-extension:// * 页面(我认为这是一个巨大的安全问题) 。我不确定你的扩展想要做什么,但是注入一个实时页面应该可行......也许你可以创建一些API来在你的服务器上生成一个新的空白页面,只要 chrome.runtime.onMessage.addListener 触发?



编辑



所以你不能将 注入 chrome-extension:// * 页面,但是你可以将消息传递给它们并使用如下所述,这些新页面中的一些Chrome API子集。所以使用消息传递,你将能够完全按你想要的(修改新的页面),尽管以迂回的方式。这是一个非常简单的概念证明,适用于我:

eventPage.js:

  chrome.runtime.onMessage.addListener(
函数(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(
函数(request,sender,sendResponse){
if(request.action ==setBackground)document。 body.style.background =red;
});


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:

// ... 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. 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. 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:

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.

What's wrong? How can I create a new tab, load an HTML page and then turn its background red?

解决方案

The problem is that you cannot inject scripts into chrome-extension://* pages (which your blankpage.html is).

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). 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?

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

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扩展程序:创建选项卡,然后将内容脚本注入到它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆