Firefox 附加组件:(本机应用程序 + 内容脚本 + 后台脚本)消息传递

Firefox add-on: (Native app + Content Script + Background script) messaging

我正在开发一个简单的插件,它可以解析页面文本,例如 twitter.com,然后向它发送外部脚本并接收响应。 我目前的工作流程是这样的:

  1. 从内容脚本连接到后台脚本。

  2. 然后从后台脚本连接到原生App并接收响应

  3. 格式化并将响应传递给内容脚本,最终可以更改 DOM。

我在连接到后台脚本时收到以下错误。 错误:

Error: Attempt to postMessage on disconnected port

错误出现在行 content.js:10:17 上,即:

myPort.postMessage({idx: i, str: "they clicked the page!"});

我无法解决这个错误。

content.js

console.log("LOADED!");
var currentTweetIndex = 0;
var tweets = null;
var myPort = browser.runtime.connect({name:"port-from-cs"}); //Connect to background script
//myPort.postMessage({str: "hello from content script"});

function AnalyzeTweets(){
        tweets = document.getElementsByClassName('tweet-text');
        for(var i = 0; i < tweets.length; i++) {
                myPort.postMessage({idx: i, str: "they clicked the page!"});
        }
}
function ColorTweet(index, tweet_class) {
        var A = tweets[index];
        if(tweet_class == "neutral"){
                color = "green";
        } else if (tweet_class == "toxic"){
                color = "yellow";
        } else if (tweet_class == "hateful") {
                color = "red";
        } else {
                console.log("UNKNOWN CLASS RECEIVED");
        }
        A.parentElement.style.backgroundColor = color;
}

myPort.onMessage.addListener(function(m) {
        console.log("In content script, received message from background script: ");
        console.log(m.idx + ": " + m.tweet_class);
        ColorTweet(m.idx, m.tweet_class);
});
document.body.addEventListener("click", function() {
        AnalyzeTweets();
        //       myPort.postMessage({str: "they clicked the page!"});
});

background.js

/* On startup, connect to the "ping_pong" app. */
var port = browser.runtime.connectNative("ping_pong");
var portFromCS; // connection from content script

/* Listen for messages from the native app. */
port.onMessage.addListener((response) => {
        console.log("Received: " + response);
        portFromCS.postMessage({tweet_class: "toxic", idx: 1});
        // Send response to content script
});

/* On a click on the browser action, send the app a message. */
browser.browserAction.onClicked.addListener(() => {
        console.log("Sending:  pinggasdfasdfas");
        port.postMessage("tested!");
});

////////////////////////////////////////////////////////////////////
/// Listen for connection from content-script
function connected(p) {
        portFromCS = p;
        portFromCS.onMessage.addListener(function(m) {
                console.log("> In background script, received message from content script")
                console.log(m);
                port.postMessage(m);
        });
}
browser.runtime.onConnect.addListener(connected);
//browser.browserAction.onClicked.addListener(function() {
//       portFromCS.postMessage({tweet_class: "toxic", idx: 1});
//});

manifest.json

{
        "description": "Native messaging example add-on",
        "manifest_version": 2,
        "name": "Native messaging example",
        "version": "1.0",
        "icons": {
                "48": "icons/message.svg"
        },

        "applications": {
                "gecko": {
                        "id": "ping_pong@example.org",
                        "strict_min_version": "50.0"
                }
        },

        "background": {
                "scripts": ["background.js"]
        },

        "content_scripts": [
                {
                        "matches": ["*://*.twitter.com/*"],
                        "js": ["content.js"]
                }
        ],

        "browser_action": {
                "default_icon": "icons/message.svg"
        },

        "permissions": ["nativeMessaging"]
}

显然,上述逻辑是可行的。问题是在加载插件后发生任何变化,我们需要重新加载选项卡以设置 native-app + background-script + content-script 之间的连接,否则会抛出上述错误。