tabs.executeScript()未在扩展的内容页面中注入脚本

erv*_*erv 3 javascript firefox-addon firefox-addon-webextensions

我刚刚开始学习如何在Firefox中创建自己的插件。我正在使用webExtensions,尽管我发现很难获得全面的文档(我认为是因为它仍然是一个新的实现?)。代码似乎都可以正常工作,并且在executeScript调用之后完成了“ onExecuted”功能。但是我注入的脚本(output.js)似乎没有启动。运行代码后,我在javascript控制台中收到以下错误:“没有匹配的消息处理程序”。我不确定注入的脚本应该是一个自包含的js文件,还是只是js命令的集合。我也尝试了后者(只是一个简单的消息框),但也没有用。

我的代码:manifest.json:

{
    "manifest_version": 2,
    "name": "ExportTabs",
    "version": "0.9",

    "description": "Export/Import Tabs",
    "icons": {
        "48": "icons/export48.png"
    },

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

    "applications": {
        "gecko": {
            "id": "938745934875@example.com"
        }
    },

    "browser_action": {
        "default_icon": "icons/export.png",
        "default_popup": "popup/popup.html" 
    }
}
Run Code Online (Sandbox Code Playgroud)

当我按下插件按钮时,我的popup.html:

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
  </head>

  <body>
    <div>
        <button onclick="save()">Save Tabs</button>
        <button onclick="view()">View Tabs</button>
    </div>

    <script src="popup.js"></script>
  </body>

</html>
Run Code Online (Sandbox Code Playgroud)

popup.js文件:

function save() {
    chrome.tabs.create({"url": chrome.extension.getURL("popup/output.html")}, onCreated);
}

function onCreated(newTab) {
    chrome.tabs.executeScript(newTab.id, {
        file: "popup/output.js",
        allFrames: true
    }, onExecuted);
}

function onExecuted(result) {
  alert("inside onExecuted");
}
Run Code Online (Sandbox Code Playgroud)

ouput.html用于新创建的标签:

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
  </head>

  <body>
    <div>testing stuff</div>
    <div id="output"></div>

  </body>

</html>
Run Code Online (Sandbox Code Playgroud)

以上页面的output.js:

//output.js
(function() {
    alert("inside output.js");
})();
Run Code Online (Sandbox Code Playgroud)

我应该补充说,我有noscript插件,因此尝试使用“全局允许脚本”进行尝试,但仍然会出现相同的错误。为任何帮助加油。

编辑:我尝试用替换file: "popup/output.js",executeScript方法中的code: 'alert("hello");',,但仍然不起作用。

信息从OP发布的答案中转移:
凹凸。我在另一个带有ff50.something(beta通道)的盒子上尝试了此代码,并且注入甚至没有使“ onExecuted”生效。但这不会引发任何错误。基本上弹出窗口起作用,然后此后什么也没发生。

Nin*_*rry 6

个别问题分析

问题“没有匹配的消息处理程序”

显示消息“没有匹配的消息处理程序”是Firefox 49之前的版本中的一个已知错误。该错误记录为Bug 1254003

问题“ executeScript不注入脚本”

在49+版本中,由于记录在案的限制,它仍然不起作用:

您只能将代码注入到可以使用匹配模式表示URL的页面中:这意味着,其方案必须是“ http”,“ https”,“ file”,“ ftp”之一。这意味着您不能将代码注入浏览器的任何内置页面中,例如about:debugging,about:addons或打开新的空白标签时打开的页面。

因此,您不能tabs.executeScript()用来将脚本插入从您自己的扩展加载的内容中。当我用从Web加载页面替换从扩展加载页面时,该示例起作用:

function save() 
{
    chrome.tabs.create({"url": "https://en.wikipedia.org/wiki/Bacon"}, onCreated);
}
Run Code Online (Sandbox Code Playgroud)

如果要在从扩展程序加载的页面中执行代码,请通过在内容页面中加载脚本文件来直接执行JavaScript

如果需要将参数传递给已加载的内容页面中的脚本,则可以在打开选项卡的脚本与打开的选项卡中的脚本之间发送消息。

请参阅Content Scripts文档上的“与后台脚本通信”一章。虽然文档专门涉及清单文件中的“ content_scripts”,但有关通信的说明也适用于您的情况。

样例代码:

Save在的功能popup.js

function onCreated(newTab) 
{
    // Use setTimeOut to give the loaded page some time to register the message listener
    setTimeout(onCreatedInner, 500);
    function onCreatedInner()
    {   
        console.log("oncreated " +   " " +  newTab.id);
        chrome.runtime.sendMessage(42);
    }
}
Run Code Online (Sandbox Code Playgroud)

output.js

chrome.runtime.onMessage.addListener(notify);

function notify(message) 
{
    window.alert(message);

}
Run Code Online (Sandbox Code Playgroud)

问题“弹出窗口中的JavaScript代码未执行”

在朋友的设置中,您遇到了另一个问题:默认情况下,不允许您在Firefox的Web扩展的内容页面中使用内联脚本。您应该看到在浏览器控制台中出现错误

内容安全策略:页面设置阻止自我加载资源

因此,不要通过保存按钮使用内联“ onclick”,而是从JavaScript脚本动态分配onclick事件。如何更改popup.html

<button onclick="save" id="buttonSave">Save Tabs</button>
<button >View Tabs</button>
Run Code Online (Sandbox Code Playgroud)

在以下代码开头添加的代码popup.js

var elem = document.getElementById("buttonSave");
elem.onclick  = save;
Run Code Online (Sandbox Code Playgroud)

完整的工作示例

这是按预期工作的完整最小示例代码:

文件 manifest.json

{
    "manifest_version": 2,
    "name": "ExportTabs",
    "version": "0.9",

    "description": "Export/Import Tabs",
    "icons": {
        "48": "icons/export48.png"
    },


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

    "applications": {
        "gecko": {
            "id": "938745934875@example.com"
        }
    },

    "browser_action": {
        "default_icon": "icons/export.png",
        "default_popup": "popup/popup.html" 
    }
}
Run Code Online (Sandbox Code Playgroud)

文件 popup.html

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
  </head>

  <body>
    <div>
        <button onclick="save" id="buttonSave">Save Tabs</button>
        <button >View Tabs</button>
    </div>

    <script src="popup.js"></script>
  </body>

</html>
Run Code Online (Sandbox Code Playgroud)

文件 popup.js

// Register onclick-Event for Save Button
var elem = document.getElementById("buttonSave");
elem.onclick  = save;

function save() 
{
     chrome.tabs.create({"url": chrome.extension.getURL("popup/output.html")}, onCreated);
}

function onCreated(newTab) 
{
    // Use setTimeOut to give the loaded page some time to register the message listener
    setTimeout(onCreatedInner, 500);
    function onCreatedInner()
    {   
        chrome.runtime.sendMessage(42);
    }
}
Run Code Online (Sandbox Code Playgroud)

文件 output.html

<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
  </head>

  <body>
    <div>testing stuff</div>
    <div id="output"></div>

  </body>
  <script src="output.js"></script>

</html>
Run Code Online (Sandbox Code Playgroud)

文件 output.js

// register message handler
chrome.runtime.onMessage.addListener(notify);

function notify(message) 
{
    // Write message into page 
    var elem = document.getElementById("output");
    elem.innerText  = message;

    // Show alert
    window.alert(message);
}
Run Code Online (Sandbox Code Playgroud)

  • @erv如果您有问题的更多详细信息,请更新问题,而不要添加评论。在那里,您还完全支持格式化源代码。在注释中,您可以使用反引号`标记源代码。 (2认同)