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

问题描述 投票:0回答:1

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

我的代码: 清单.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": "[email protected]"
        }
    },

    "browser_action": {
        "default_icon": "icons/export.png",
        "default_popup": "popup/popup.html" 
    }
}

按下插件按钮时我的 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>

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

新创建选项卡的ouput.html:

<!DOCTYPE html>

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

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

  </body>

</html>

上述页面的output.js:

//output.js
(function() {
    alert("inside output.js");
})();

我应该补充一点,我有 noscript 插件,所以尝试过“全局允许脚本”,但它仍然给出相同的错误。 为任何帮助干杯。

编辑:我尝试将executeScript方法中的

file: "popup/output.js",
替换为
code: 'alert("hello");',
,但仍然不起作用。

信息来自OP发布的答案:
撞。我在另一个带有 ff50.something(测试版通道)的盒子上尝试了这段代码,注入甚至没有使“onExecuted”。但它不会抛出任何错误。基本上弹出窗口起作用了,然后就没有任何反应了。

javascript firefox-addon firefox-addon-webextensions
1个回答
9
投票

个别问题分析

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

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

问题“
executeScript
未注入脚本”

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

您只能将代码注入到 URL 可以用 a 表示的页面中 matchpattern:意思是,它的scheme必须是“http”,“https”之一, “文件”、“ftp”。这意味着您不能将代码注入到任何 浏览器的内置页面,例如 about:debugging、about:addons 或 当您打开新的空选项卡时打开的页面。

因此,您不能使用

tabs.executeScript()
将脚本注入到从您自己的扩展加载的内容中。当我将从扩展程序加载页面替换为从网络加载页面时,该示例有效:

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

当您想在从扩展程序加载的页面中执行代码时,可以通过在内容页面中加载脚本文件来直接执行 JavaScript

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

请参阅内容脚本文档上的“与后台脚本通信”一章。虽然文档专门针对清单文件中的“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);
    }
}

output.js

chrome.runtime.onMessage.addListener(notify);

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

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

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

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

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

popup.html

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

popup.js
开头添加代码:

var elem = document.getElementById("buttonSave");
elem.onclick  = save;

完整的工作示例

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

文件

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": "[email protected]"
        }
    },

    "browser_action": {
        "default_icon": "icons/export.png",
        "default_popup": "popup/popup.html" 
    }
}

文件

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>

文件

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

文件

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>

文件

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);
}
© www.soinside.com 2019 - 2024. All rights reserved.