无法从后台脚本成功 运行 executeScript,除非我先加载弹出窗口 page/script

Can't successfully run executeScript from the background script unless I load the popup page/script first

我试图 运行 使用键盘快捷键从我的后台脚本执行脚本,它不起作用并且 returns:

Error: No window matching {"matchesHost":[]}

但是如果我只是打开弹出页面,关闭它,然后做同样的事情,一切正常。

我在使用 Beastify 示例时进行了最小的更改,重新创建了问题。这是代码:

manifest.json

{
    ... (not interesting part, same as in beastify)

    "permissions": [
    "activeTab"
    ],  

    "browser_action": {
        "default_icon": "icons/beasts-32.png",
        "default_title": "Beastify",
        "default_popup": "popup/choose_beast.html"
    },

    "web_accessible_resources": [
        "beasts/frog.jpg",
        "beasts/turtle.jpg",
        "beasts/snake.jpg"
    ],

My additions start here:

    "background": {
        "scripts": ["background_scripts/background_script.js"]
    },

    "commands": {
        "run_content_test": {
            "suggested_key": {
                "default": "Alt+Shift+W"
            }
        }
    }
}

popup/choose_beast.js(与原文相同)

/*
Given the name of a beast, get the URL to the corresponding image.
*/
function beastNameToURL(beastName) {
  switch (beastName) {
    case "Frog":
      return browser.extension.getURL("beasts/frog.jpg");
    case "Snake":
      return browser.extension.getURL("beasts/snake.jpg");
    case "Turtle":
      return browser.extension.getURL("beasts/turtle.jpg");
  }
}

/*
Listen for clicks in the popup.

If the click is on one of the beasts:
  Inject the "beastify.js" content script in the active tab.

  Then get the active tab and send "beastify.js" a message
  containing the URL to the chosen beast's image.

If it's on a button wich contains class "clear":
  Reload the page.
  Close the popup. This is needed, as the content script malfunctions after page reloads.
*/
document.addEventListener("click", (e) => {
  if (e.target.classList.contains("beast")) {
    var chosenBeast = e.target.textContent;
    var chosenBeastURL = beastNameToURL(chosenBeast);

    browser.tabs.executeScript(null, {
      file: "/content_scripts/beastify.js"
    });

    var gettingActiveTab = browser.tabs.query({active: true, currentWindow: true});
    gettingActiveTab.then((tabs) => {
      browser.tabs.sendMessage(tabs[0].id, {beastURL: chosenBeastURL});
    });
  }
  else if (e.target.classList.contains("clear")) {
    browser.tabs.reload();
    window.close();

    return;
  }
});

background_scripts/background_script.js(我加的)

browser.commands.onCommand.addListener(function(command) {
    var executing = browser.tabs.executeScript(
            null, 
            {file: "/content_scripts/content_test.js"});

    executing.then(
            function (res){
                console.log("started content_test.js: " + res);
            }, 
            function (err){
                console.log("haven't started, error: " + err);
            });
});

content_scripts/content_test.js(我加的)

alert("0");

我跳过整个 content_scripts/beastify.js 因为它与它无关 (IMO),但可以找到 here .

现在,我知道即使之前没有打开弹出页面,后台脚本 运行 也会收到消息,因为我看到它无法执行脚本。我不知道是什么导致了这种行为,也不知道是否有办法解决它。

注意:我尝试添加权限,例如"tabs"甚至"all_urls",但它没有改变任何东西。

注意 2: 我从 about:debugging 页面 运行 将该插件作为临时插件安装,但我尝试在正常的非受限页面上执行脚本(例如,在此页面上我可以重现问题)。

非常感谢大家!

// in manifest.json

    "permissions": [
       "<all_urls>",
       "activeTab"
    ],

对我有用(Firefox 50,Mac OS X 10.11.6)。

我在使用原始版本时收到了与您描述的完全相同的错误消息

    "permissions": [
       "activeTab"
    ],

所以添加 "<all_urls>" 似乎解决了这个问题。但是,您说当您在权限中包含 "all_urls" 时仍然遇到问题,所以我不确定我这样做的方式是否解决了您自己的设置中的问题。

编辑:我想,就它可能带来的安全风险而言,给予任何网络扩展如此广泛的权限是否明智是一个单独的重要考虑因素。

(我本可以将其作为评论发布,但我还没有足够的声誉来添加评论。)