sendMessage from extension background or popup to content script doesn't work

BackgroundGoogle Chrome-ExtensionSendmessageContent Script

Background Problem Overview


I know that question has been repeatedly asked in different ways, but I tried to go through all the answers (hopefully I didn't miss anyone) and none of them worked for me.

Here is my extension's code:

manifest:

{
"name": "test",
"version": "1.1",
"background": 
{ 
	"scripts": ["contextMenus.js"]
},

"permissions": ["tabs", "<all_urls>", "contextMenus"],

"content_scripts" : [
	{
		"matches" : [ "http://*/*" ],
		"js": ["jquery-1.8.3.js", "jquery-ui.js"],
		"css": [ "jquery-ui.css" ],
		"js": ["openDialog.js"]
	}
],

"manifest_version": 2
}

contextMenus.js

function onClickHandler(info, tab) {
    if (info.menuItemId == "line1"){

  	  alert("You have selected: " + info.selectionText);

	  chrome.extension.sendMessage({action:'open_dialog_box'}, function(){});

	  alert("Req sent?");
	
   	}
}

chrome.contextMenus.onClicked.addListener(onClickHandler);

chrome.runtime.onInstalled.addListener(function() {

  chrome.contextMenus.create({"id": "line1", "type": "normal", "title": "I'm line 1",     "contexts":["selection"]});

});

openDialog.js

chrome.extension.onMessage.addListener(function(msg, sender, sendResponse) {

  if (msg.action == 'open_dialog_box') {
	alert("Message recieved!");
  }
});

The two alerts of the background page work, while the one of the content_script doesn't.

console log's message: Port error: Could not establish connection. Receiving end does not exist.

Where is my fault?

Background Solutions


Solution 1 - Background

In your background page you should call

chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
    chrome.tabs.sendMessage(tabs[0].id, {action: "open_dialog_box"}, function(response) {});  
});

instead of using chrome.extension.sendMessage as you currently do.

The chrome.tabs variant sends messages to content scripts, whereas the chrome.extension function sends messages to all other extension components.

Solution 2 - Background

@apsillers is correct. Also don't forget to return true in your content-script listener or it might close too early.

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    console.log(message)
    return true
});

Solution 3 - Background

Here's an example of a background script that sends a message to the content-script file.

background.js

chrome.tabs.sendMessage(tabs[0].id,"your message"); 

content-script/content.js

chrome.runtime.onMessage.addListener(function (response, sendResponse) {
          console.log(response);
});

Solution 4 - Background

The problem with the provided solutions is that they raise other errors (Which break my Google Chrome)

@apsillers solution works but the callback raises errors!

How it should look like

// Background.js

chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id, {action: "open_dialog_box"});  
});

Now in Content scripts as provided by @Ronan Ca which builds upon @apsillers solution. It is Not ideal to return since we removed the callback from the background script.

// ContentScripts.js

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log(message)
// return true <- this and the callback in background.js are what caused a crash in extensions page of my Google chrome
});

The background console won't open If I try to do it with callbacks. (It's that bad of a crash)

Solution 5 - Background

My use-case required sending a message to the background script from a webpage. I used chrome.runtime.onMessageExternal to catch this message.

Inside of this listener I was basically forwarding the message over to my content script so it could do its thing, but I could not figure out why my content script onMessage listener wouldn't catch the message.

Turns out by waiting for 1 second before sending the message from the webpage (I was basically doing it on load) I was able to see the message hitting my content script.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSubwayView Question on Stackoverflow
Solution 1 - BackgroundapsillersView Answer on Stackoverflow
Solution 2 - BackgroundRonan CaView Answer on Stackoverflow
Solution 3 - BackgroundSaravanan SelvamohanView Answer on Stackoverflow
Solution 4 - BackgroundSal7_oneView Answer on Stackoverflow
Solution 5 - BackgroundNikita JerschowView Answer on Stackoverflow