Javascript 后台脚本和内容脚本之间的连接丢失/消息

Javascript 后台脚本和内容脚本之间的连接丢失/消息,javascript,google-chrome-extension,Javascript,Google Chrome Extension,我对创建Chrome扩展还不熟悉,现在面临着一个问题,就是如何保持后台脚本(事件页面)与内容脚本之间的连接处于打开状态。我找了一整天,运气不好。大多数示例都使用非持久性连接 我的扩展需要将一些数据从网页发送到内容脚本。从内容脚本到后台脚本,其中本机消息与本机应用程序通信,本机应用程序返回一个答案,该答案通过后台脚本传递到内容脚本,最后在网页上再次收到 我能够将消息一直传递到本机应用程序,并返回一个答案,但我的挑战是从这里传递消息,因为后台脚本和内容脚本之间的连接已断开 文件: manifest.

我对创建Chrome扩展还不熟悉,现在面临着一个问题,就是如何保持后台脚本(事件页面)与内容脚本之间的连接处于打开状态。我找了一整天,运气不好。大多数示例都使用非持久性连接

我的扩展需要将一些数据从网页发送到内容脚本。从内容脚本到后台脚本,其中本机消息与本机应用程序通信,本机应用程序返回一个答案,该答案通过后台脚本传递到内容脚本,最后在网页上再次收到

我能够将消息一直传递到本机应用程序,并返回一个答案,但我的挑战是从这里传递消息,因为后台脚本和内容脚本之间的连接已断开

文件:

manifest.json

{
  "manifest_version": 2,

  "name": "MyExtenesion",
  "description": "MyExtension",
  "version": "0.1",

  "background": {
    "scripts": ["eventPage.js"],
    "persistent": false
  },
  "browser_action": {
    "default_title": "MyExtension",
    "default_icon": "icon.png"    
  },
  "content_scripts": [
    {
        "matches": ["<all_urls>"],
        "js": ["content.js"]
    }
  ],
  "externally_connectable": {
    "matches": ["http://localhost/*"]
   },
  "permissions": [
    "tabs",
    "nativeMessaging",
    "http://localhost:5661/*"
  ]
}
eventPage.js

var port = chrome.runtime.connect();

// Event sent from the web page is caught and the data is sent to the event page (background script)
document.addEventListener("MsgToContent", function(data) {  
    console.log('1 content MsgToContent');
    port.postMessage(data.detail);
});

// When the event page script connects to the content script
chrome.runtime.onConnect.addListener(function(port) {

    // When a message to the content script has been received
    //port.onMessage.addListener(function(msg) {
    chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
        alert('fra content: ' + msg);

        sendResponse();
    });
});
var contentPort = null;

// Connect to native app
var port = chrome.runtime.connectNative('com.nativeApp');

chrome.tabs.onActivated.addListener(function(tabId, changeInfo, tab) {

    // When the page/tab loads, connect to its content script scope
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {

        contentPort = chrome.tabs.connect(tabs[0].id);

        contentPort.onDisconnect.addListener(function() {
            console.log('tabs.query contentPort onDisconnect');
        });

        // When the content script has received a message
        contentPort.onMessage.addListener(function(msg) {
            console.log('x eventPage currentPort onMessage');
        });
    });
});

chrome.runtime.onConnect.addListener(function(pPort) {
    console.log('2 eventPage onConnect');

    // When receiving a message from the content script
    pPort.onMessage.addListener(function(msg) {
        console.log('3 eventPage onConnect onMessage');
        // Send message to the native app
        port.postMessage({ text: msg });  
    });
});

// Handles incoming messages from the native app
port.onMessage.addListener(function(msg) {
  console.log('4 eventPage port onMessage');
  contentPort.postMessage(msg); 
});
问题出在eventPage.js中。我尝试将contentPort设置为与内容脚本的当前连接,但当我从本机应用程序进入onMessage事件时(我想在其中传递消息),我得到错误:

Error in event handler for (unknown): Error: Attempting to use a disconnected port object
在contentPort.postMessage(msg)行中

如何保持连接打开,以便我可以发回消息?我感谢任何能帮助我解决这个问题的提示


我真的不知道最好的沟通方式,所以欢迎提供任何建议。

可能与此重复:谢谢您的评论。我很难看到解决方案如何转化为我的问题。在回答中,建议在页面操作中插入内容脚本。我不使用它,我需要我的内容脚本一直运行(不仅仅是页面上的操作),因为它侦听来自网页的消息。我在尝试与服务器通信时发现了相同的问题。与后台的连接似乎只允许“快速”操作,否则它永远不会回拨。我自己的解决方案是将所有发送的后台消息封装在一个函数中,该函数根据唯一的ID存储回调(Ajax调用也是如此),然后捕获来自后台的返回消息,找到任何存储的与ID匹配的回调并执行该回调。它使代码模式看起来像您期望的那样。