【问题标题】:tabs.executeScript() not injecting script in content page of extensiontabs.executeScript() 不在扩展的内容页面中注入脚本
【发布时间】:2016-10-25 05:40:38
【问题描述】:

我刚刚开始学习如何在 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" 
    }
}

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

新创建的标签的输出.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 插件,所以用“全局允许脚本”尝试了这个,它仍然给出了同样的错误。 为任何帮助干杯。

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

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

【问题讨论】:

    标签: javascript firefox-addon firefox-addon-webextensions


    【解决方案1】:

    个别问题分析

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

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

    问题“executeScript不注入脚本”

    在 49+ 版本中,由于这个documented restriction,它仍然无法工作:

    您只能将代码注入到其 URL 可以使用 匹配模式:意思是,它的方案必须是“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 documentation 上的“与后台脚本通信”一章。虽然文档专门针对清单文件中的“content_scripts”,但有关通信的说明也适用于您的情况。

    示例代码:

    popup.js 中的函数 Save

    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": "938745934875@example.com"
            }
        },
    
        "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);
    }
    

    【讨论】:

    • 谢谢九。几个问题。 FF50 甚至不会创建一个新标签,更不用说加载任何东西了。我对 popup.js 使用了以下内容:codefunction save() { chrome.tabs.create({"url": "en.wikipedia.org/wiki/Bacon"});另一个问题是,据我所知,您只能在 content_script 和后台脚本之间进行通信,而不是通过 output.html 代码加载的脚本。但我无法加载内容脚本,因为它只接受您所说的有限匹配模式。我的 output.html 是一个本地文件。有没有一种简单的方法可以将它托管在某个地方以通过 http 加载?
    • nb:在上面由于某种原因它添加了一个不存在的分号。代码是: chrome.tabs.create({"url": "en.wikipedia.org/wiki/Bacon"});编辑:我放弃了。它也在这里添加了它。忽略培根后的分号”。它也被超链接并删除了 h t t p 等。
    • @erv 我已经用更多细节更新了答案。请更具体地说明您遇到的问题。始终在浏览器控制台中检查错误或警告。
    • @erv 如果您对某个问题有更多详细信息,请更新问题而不是添加 cmets。在那里,您还可以完全支持格式化源代码。在 cmets 中,您可以使用反引号 ` 来标记源代码。
    • 干杯,九,现在适用于 ff50。关于内容安全错误,您是对的。我错过了它,因为我只查看控制台上的 javascript 错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-17
    • 2011-12-11
    • 1970-01-01
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    相关资源
    最近更新 更多