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