Druzion Druzion - 1 month ago 20
Javascript Question

Chrome / Firefox extension - Content script not listening for messages

I am developing an extension for both Chrome and Firefox, and I have come across a problem.

Basically, I am trying to get a content script to listen to messages using

chrome.runtime.onMessage.addListener(...)
, however it doesn't seem to work.

I tested it by sending a message from the content script. The background script (
ml.js
) had a listener that worked fine, but the lsitener in the content script just didn't get the message.

You can view the code in this Gist (or below).

manifest.json
:

{
"manifest_version": 2,
"name": "Messaging Extension",
"version": "1.0.0",
"background": {
"scripts": ["ml.js"]
},
"content_scripts": [
{
"matches": ["*://*.google.co.uk/*"],
"js": ["cs.js"],
"run_at": "document_end"
}
]
}


ml.js
:

// When receive message...
chrome.runtime.onMessage.addListener(function(message) {
if (message.key) {
console.log('ML: First message received')
// Send another message
chrome.runtime.sendMessage({
'foo': 'bar'
})
}
})


cs.js
:

// Send message to ml.js
chrome.runtime.sendMessage({
'key': 'value'
})
chrome.runtime.onMessage.addListener(function(message) {
console.log('CS: Second message received')
})


When tested in Firefox (by loading the add-on at about:debugging and then visiting Google),
cs.js
sent the message, and
ml.js
logged the message to the console, however
cs.js
didn't log the message.

I'll appreciate some help, thanks!

Answer

Using runtime.sendMessage() (messages to background scripts):

The runtime.sendMessage() (Chrome/Firefox) method is used to send messages to scripts that are running in the background context (background scripts, popup scripts, etc). Even when it is used to send messages from a script that is in the background context (e.g. to communicate between a popup script and a background script), it will be received by other currently listening background context scripts, but not the script that is sending it.

To quote the Google Chrome runtime.sendMessage() documentation (emphasis mine):

If sending to your extension, the runtime.onMessage event will be fired in every frame of your extension (except for the sender's frame)...

Sending a message to your content script (tabs.sendMessage())

If you are wanting to send a message from your background script to your content script you should be using tabs.sendMessage() (Chrome/Firefox). Alternately, you can use the connect() methods in runtime and tabs, which then provide you with a port (Chrome/Firefox).

References: