Port error: Could not establish connection. Receiving end does not exist. In Chromiume

Some of the other answers here have good debugging advice or small pieces of the puzzle, however if you want to inject into (3rd party) web pages like me, then no answers here listed the correct components.

There are 4 steps:

  • an external background listener,
  • the foreground message sender,
  • injecting extension id for the message sender
  • and a rule in the manifest to link everything together.

The example below should be everything you need to allow you to inject a js that sends messages from any page on google.com to your own extension

First in the manifest.json you need to add the messaging rules which are described here:

"externally_connectable": {
    "matches": ["*://*.google.com/*"]
}

Then in your background script or page, you need an external listener (Not the regular chrome.runtime.onMessage.addListener which has been mentioned in msot answers), this is described here:

chrome.runtime.onMessageExternal.addListener( (request, sender, sendResponse) => {
    console.log("Received message from " + sender + ": ", request);
    sendResponse({ received: true }); //respond however you like
});

Once you have these parts, you can use a message sender as you usually do, but with the extension id as first parameter:

chrome.runtime.sendMessage(myExtId, { /* whatever you want to send goes here */ },
    response => {
         /* handle the response from background here */
    }
);

If you don’t know how to get the external id I used as first param, you can inject your extension id like below. This is required because chrome.runtime.id and @@extension_id both fail to work in injected scripts:

//create a script tag to inject, then set a variable with the id in that script
let idScript = document.createElement("script");
idScript.setAttribute("type", "application/javascript");
idScript.textContent="var myExtId = "" + chrome.runtime.id +'";';
let parent = ( document.head || document.documentElement );
parent.insertBefore( idScript, parent.firstChild );

//inject and run your other script here

idScript.remove(); //then cleanup 

Because we set it as a var, the other script can directly access the value now

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)