I am new to the world of creating Chrome Extensions, and is facing a problem of keeping a connection open from my background script (event page) to the content script. I have been searching all day with no luck. Most examples are with non-persistent connections.
My extension needs to send some data from a web page to the content script. From the content script to the background script, where a native message communicates with a native application, which returns an answer that goes through the background script to the content script and finally is received at the web page again.
I am able to pass the message all the way to the native application and have an answer returned, but my challenge is passing it on from here as the connection between the background script and the content script is dead.
The files:
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/*"
]
}
content.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();
});
});
eventPage.js
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);
});
The problem is in the eventPage.js. I try to make contentPort the current connection to the content script, but when I get into the onMessage event from the native app, where I want to pass on the message, I get the error:
Error in event handler for (unknown): Error: Attempting to use a disconnected port object
In the line contentPort.postMessage(msg);
How do I keep the connection open, so I can send a message back? I appreciate any hints that can help me solve this issue.
I am not really aware of the best way of doing the communication, so any advices are most welcome.