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

前端 未结 17 2354
甜味超标
甜味超标 2020-12-05 09:26

I\'m developing an extension in Chrome, and there\'s a problem. In my inject.js, I make a request like:

chrome.extension.sendRequest({command:         


        
相关标签:
17条回答
  • 2020-12-05 09:43

    I place chrome.runtime.sendMessage and chrome.runtime.onMessage.addEventListener in content script intowindow.onload or self-execution function and it's work. And in manifest I use

    "background": { "scripts": ["background.js"], "persistent": false },

    manifest_version: 2. Hope it helps.

    0 讨论(0)
  • 2020-12-05 09:44

    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

    0 讨论(0)
  • 2020-12-05 09:44

    If the message handling is in a pop-up window or html page that is not always visible, before I send any message, I check if the pop-up is visible, like so:

    function isPopupVisible() { //required for firefox before sending any message ore we get the stupid message 'receiveing end does not exist'
        var views = chrome.extension.getViews({ type: "popup" }); //https://stackoverflow.com/questions/8920953/how-determine-if-the-popup-page-is-open-or-not
        if (views.length > 0) {
            console.log("Popup is visible");
            return true;
        }
        return false;
    }
    
    0 讨论(0)
  • 2020-12-05 09:46

    The problem could be that sendRequest() and onRequest have been deprecated and replaced with sendMessage() and onMessage. Since a recent Chrome 20 update they seem to be gone completely.

    The official documentation on Message Passing doesn't even mention sendRequest() anymore.

    Here is a link which documents the change a little bit: http://codereview.chromium.org/9965005/

    0 讨论(0)
  • 2020-12-05 09:47

    I found myself having the same issue as you describe here. The solution I found that works for me is to use a backgroundpage instead of a background script, like so:

    "background_page": "src/background.html",
      // maybe this seems to work instead of background { scripts [] }
    
      /* this gives a Port error: Could not ...
      "background": {
      "scripts": ["src/background.js"]
      },
      */
    

    I hope this works for you too.

    0 讨论(0)
  • 2020-12-05 09:52

    I'm using sendMessage and onMessage for communication too, and in my workflow I first send a message from injected.js to my background.js and I also got "Port error: Could not establish connection. Receiving end does not exist." error.

    So I decided to deal with using the responses functionalities ( like ACK ), and if background doesn't respond I keep trying with a setTimeout like so.

    //background.js

    ...
    chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
    ...
    //some code
    
    sendResponse({status: 'everything ok'})
    return true;    
    });
    

    //injected.js

    var myInjectedFunctionality = function() {
    
        chrome.extension.sendMessage({method: "Steroids:loadScripts"}, function(res) {
            if(res && res.status) {
                } else {
                    setTimeout(myInjectedFunctionality, 3000);
                }
        });
    };
    myInjectedFunctionality();
    

    My code is now running properly so I think that the explanation is easy to view. Chrome don't prepare Background.js and connection stuffs when it inject your code in the pages where you want to, and so makes nobody listen for your sent message, so if no one is listening, just keep trying like I do.

    0 讨论(0)
提交回复
热议问题