0
votes

I am developing a chrome extension that needs to send message from extension background page to content script but I keep getting the following error no matter what I do: "Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist."

The message that the background script is sending, is being fetched by an API which runs on every url change.

Here is the manifest.json file:

{
  "manifest_version": 2,
  "name": "tool",
  "description": "help tool",
  "version": "1.0",
  "icons": {
    "16": "icons/icon16.png",
    "32": "icons/icon32.png",
    "48": "icons/icon48.png",
    "128": "icons/icon128.png"
  },

  "page_action": {
    "default_icon": "icons/icon128.png",
    "default_popup": "src/popup.html",
    "default_title": "tool"
  },

  "background": {
    "scripts": [
                "src/background.js"
                ],
    "persistent": true
  },

  "web_accessible_resources": [
    "src/content.css"
  ],

  "content_scripts": [
    {
    "matches": [
      "https://*"
    ],
    "js": [
      "src/jquery-3.4.1.min.js",
      "src/content.js"
      ],
      "css": [
        "src/content.css"
      ]
    }
  ],

  "permissions": [
    "tabs",
    "Api URL"
  ]
}

Here is the code which I am using in the background and content script:

background.js- callApi is being called on every url change through chrome.tabs.onUpdated.addListener function:

   chrome.tabs.onUpdated.addListener(() => {
     chrome.tabs.query({active: true, currentWindow: true},function(tabs) {
       var tab = tabs[0];
       var url = tab.url;
       var para = "url=" + url
       console.log(para)
       callApi(para)
     })
  })

    const callApi = (para) =>   {
    var url = "API URL" + para
    fetch(url)
        .then((response) => {
            return response.text();
     })
     .then((data) => {
        console.log(data);
        connectToCurrentTab(data);
     })
   }

    function getCurrentTabId(cb) {
        var query = {active: true, currentWindow: true};
        chrome.tabs.query(query, function(tabArray) {
            cb(tabArray[0].id)
        });
    }

    function connectToCurrentTab (data) {
        getCurrentTabId(function(currentTabId) {
           var port = chrome.tabs.connect(currentTabId, {name: "knock"})

           port.postMessage(data);
           port.onMessage.addListener((msg) => {
               return true;
           });
        });
    }

content.js:

chrome.runtime.onConnect.addListener(port => {
    console.log('connected ', port);
    if (port.name === 'knock') {
       port.onMessage.addListener(function(msg) {
           var data = JSON.parse(msg) 
             port.postMessage({data: "received"});
         });
    }
});

I am able to get the data in the content script but it is also showing the error. Can anyone help me to solve this? Any help is greatly appreciated.

1
It means that connectToCurrentTab was called when the active tab didn't have a content script running. It can be a chrome:// or chrome-extension:// tab which can't run content scripts. For http/https tabs the reason may be that your content script declaration doesn't have "run_at":"document_start" and the tab was still loading when connectToCurrentTab was invoked. The posted fragment of code is fine by itself, but it's not enough to diagnose the problem. Note, the tab(s) should be manually reloaded after reloading the extension. - wOxxOm
@wOxxOm kindly look at the updated question. Also do we need to fix the error before submitting request for publishing it in the chrome webstore? Thank you for your response. - yash03agrawal
The info is still insufficient (I don't see manifest.json, and whether the active tab has a http/https URL), but the code seems wrong: URL may change in inactive tabs too, but you send the info to the active tab. - wOxxOm
@wOxxOm okay so basically I am creating a help extension which based on the current page will show the relevant help. So for that I am calling my API for every url changes and passing the url of the active tab to the api. Now the api will fetch data and provide it to background script which then will send to content script which then will show the help in the provided space in the active web page. I have also provided the manifest file and updated background.js file. Do have a look. - yash03agrawal
1) The content script runs only on https:// URLs per your manifest.json. 2) chrome.tabs.onUpdated is invoked on all tabs, not just the active ones, so your code should be fixed, see the documentation and use the parameters accordingly. - wOxxOm

1 Answers

0
votes

The issue got resolved. I was using a complicated process to send message to content script. Also there was error in onUpdate function. The correct way to call api on url change is:

chrome.tabs.onUpdated.addListener(
  function(tabId, changeInfo, tab) {
    if (changeInfo.url) {
      para = "url="+changeInfo.url
      callApi(para)
    }
  }
);

Thank you for helping me out.