在开发chrome扩展时,如何打开空白页面来运行脚本?

时间:2013-10-12 22:43:41

标签: javascript jquery google-chrome iframe google-chrome-extension

我正在创建一个Chrome扩展程序,需要打开一个空白页面,然后根据一些注入的脚本在这个空白窗口中打开1/2 iframe。

我的问题是如何打开一个空白窗口,我可以注入并运行JS?

我尝试打开包含about:blank网址的网页,但由于以下错误,我无法将脚本注入此页面:

chrome.tabs.create({
    url: 'about:blank'
}, function(tab) {
    chrome.tabs.executeScript(null, {
        file: 'jquery/jquery.js'
    }, function() {
        console.log('done', arguments);
    });
});

tabs.executeScript: Cannot access contents of url "about:blank".
Extension manifest must request permission to access this host.

显然,此错误消息让我认为我无权访问此网址并更新我的清单以允许访问所有网址但我遇到同样的问题。

"permissions": [
    "tabs",
    "*://*/*"
],

额外信息

我没有直接打开网址的原因是因为我有2个网址需要一个接一个地访问。这些文件是我需要查看结果的升级脚本。

执行此操作的最佳方法是打开一个页面,并在窗口的左侧和右侧有一个iframe,我可以使用我的注入脚本控制它。

1 个答案:

答案 0 :(得分:2)

您可以在扩展程序包中创建虚拟升级页面,我们称之为upgrade.html

使用它来制作你的结构并添加你想要的2个iframe。 如果要控制它,可以使用后台脚本使用消息传递在2个javascript页面之间进行通信。要从父网页传递到iframe,只需查看Invoking JavaScript code in an iframe from the parent page

中的任何答案

如果你不知道你想要预先运行的逻辑 - 尽管你应该 - 那么你可以在页面之间传递整个字符串并在另一边评估它们 - 虽然这不是你通常想要的东西去做。这是传递消息的文档:http://developer.chrome.com/extensions/messaging.html


简而言之:您的页面A包含您的内容,第B页是您的背景页面,页面C是包含2个iframe的更新页面,然后:

// A.js
var port = chrome.runtime.connect({name: "content-script"});
port.postMessage({ runScript: 'yahoo(); function yahoo; () { alert("Yahoo!"); }' });

// B.js
// The background page is only used as a proxy
var upgrade_port = null;
chrome.runtime.onConnect.addListener(function(port) {
  switch (port.name) {
    case 'content-script':
       // Also you need to query for the upgrade page and open it if it does not exist
       port.onMessage.addListener(function(msg) {
         upgrade_port.sendMessage(msg);
       });
       break;
    case 'upgrade-page':
      upgrade_port = port;
      break;
    default:
      console.warn('Unknown port name: ' + port.name);
  }
});

// C.js
var port = chrome.runtime.connect({name: "upgrade-page"});
port.onMessage.addListener(function (message) {
  if (message.runScript) {
    eval(message.runScript);
  }
});

您需要使用端口,否则您无法从一个页面与另一个页面进行通信。另外,如果您只是事先在页面C中插入JS并将其保持为静态并将参数传递给函数RPC-style(远程过程调用),又名:

,那就更好了。
// A.js
port.postMessage({action:'RPC', name:'yahoo', args:['hello', 'world', 3]});

// C.js
var RPCs = {
  yahoo: function (str1, str2, no) {
    alert(str1 + ',\n' + str2 + '\nThis is a number: ' + no);
  }
};

port.onMessage.addListener(function (msg) {
  switch (msg.action) {
    case 'RPC':
      if (!RPC[msg.name]) { console.warn('Unknown RPC: ' + msg.name); return; }
      RPC[msg.name].apply(RPC, msg.args || []);
      break;
    default:
      console.warn('Unknown action: ' + msg.action);
  }
});