6

I get this error in my simple chrome extension. I'm trying to pass some messages from background.js to my content script. The first message will be sent without problems, but the second one give me this error _generated_background_page.html:1 Unchecked runtime.lastError: The message port closed before a response was received.

I need to pass a response from the content script after the first message is recived, this because I need to remove event listener from webRequest.onCompleted otherwise I will get a loop problem with message passing. I'm not sure if I'm doing the things well also with removeListener function.

Here is my code, any help will be appreciated

contentScript.js

const m3u8 = new M3U8(); 
console.log(m3u8);
chrome.runtime.onMessage.addListener( message => {    
    console.log(message);
    chrome.runtime.sendMessage({status: 'ok'})
    const download = m3u8.start(message.url);
    download.on("progress", progress => {
        console.log(progress);
    }).on("finished", finished => {
        console.log(finished);
    }).on("error", error => {
        console.log(error);
    });
});

background.js

const sendURL = (request) => {
    chrome.tabs.sendMessage(request.tabId, {url: request.url}, response => {
        if( response.status === 'ok' ){
            chrome.webRequest.onCompleted.removeListener( sendURL )
        }
        return true;
    })
}

chrome.webRequest.onCompleted.addListener( request => {
    console.log(request);
    sendURL(request)
},{
    urls: ["https://*.myurl.net/*/*prog_index.m3u8*"],
    types: ["xmlhttprequest"]
},["responseHeaders"]);
alfaun0
  • 189
  • 1
  • 2
  • 12

1 Answers1

4

You were sending a new message, not a response. And it failed because there was no corresponding onMessage in the background script.

Let's use the simple messaging example correctly.

  1. Add sendResponse parameter to onMessage:

    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {  
    
  2. Use sendResponse instead of chrome.runtime.sendMessage

    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {  
      sendResponse({status: 'ok'});
      //.........
    });
    
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
  • ok, thank you, I will fix the code. For the listener, is the code ok instead? I'm not sure if the listener is removed – alfaun0 Aug 09 '20 at 06:04
  • It's not removed. You need to use addListener(sendURL) instead of addListener(request => { console.log(request); sendURL(request) }) – wOxxOm Aug 09 '20 at 06:06
  • I've fixed the code, I'm able to `console.log()` the response that is send from the content script. The problem is now that the message is sent in a loop and the `removeListener` will not fire. – alfaun0 Aug 09 '20 at 06:13
  • ok, I will try and let you know. the `request` will be passed implicitly to the function right? – alfaun0 Aug 09 '20 at 06:14
  • Weird that you need to call `sendResponse` to avoid the error, since the documentation states it's optional. https://developer.chrome.com/docs/extensions/reference/runtime/#method-sendMessage – Protector one Mar 20 '22 at 15:38
  • 1
    @Protectorone, see [this answer](/a/59915897/) for more info. – wOxxOm Mar 20 '22 at 16:09
  • @wOxxOm Is there an overview of possible communication channels between extension parts `background.js - content.js, content.js - popup.js, popup.js - background.js, content.js - background.js, ... ` Is it possible to communicate from any part to any part? – Legends Apr 18 '23 at 10:29
  • 1
    @Legends, there's [messaging article](https://developer.chrome.com/extensions/messaging) in the documentation. For the popup-SW route there's native navigator.serviceWorker messaging. – wOxxOm Apr 18 '23 at 11:39