Unchecked runtime.lastError: Cannot access contents of url "". Extension manifest must request permission to access this host. In manifest 3

Viewed 3380

Help me, please! I have gotten error Unchecked runtime.lastError: Cannot access contents of url. Extension manifest must request permission to access this host. and Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist. in google chrome manifest 3.

Listener from content script

chrome.runtime.onMessage.addListener(
function(req, sender, sendResponse) {
    if(req.msg === "analysis background") {
        let obj = parse();
        sendResponse(obj);
    }
        
    return true;
}
); 
); 

manifest.json

{
    "manifest_version": 3,
    "name": "extensionParser",
    "version": "1.0.0",
    "action": { 
        "default_popup": "popups/popup.html"
      },
    "background": {
        "service_worker": "background.js"
    },
    "permissions": ["tabs", "scripting",
        "http://localhost/site_for_parsing"]
}

Code from background file

const siteUrl = "http://localhost/site_for_parsing";

chrome.runtime.onConnect.addListener(port => {
    port.onMessage.addListener(msg => {
        if(msg.message === 'analysis') {
            chrome.tabs.create({active: false, url: siteUrl}, tab => {
                chrome.scripting.executeScript({
                    target: {tabId:tab.id},
                    files: ['dist/parser.js']
                }, (results) => {
                    chrome.tabs.sendMessage(tab.id, {msg: "analysis background"}, res => {
                        port.postMessage(res)
                        chrome.tabs.remove(tab.id)
                    })
                })
            });
        }

    });
});

Thank you in advance! I'm waiting your answers. Good day!

1 Answers
  1. Site permissions should be added to host_permissions, not permissions, more info.
  2. create + executeScript in ManifestV3 is bugged in Chrome older than 100 so either a) go back to ManifestV2 until Chrome 100 is stable or b) use the workaround below.

Wait for the URL to be set:

(async () => {
  const tab = await chrome.tabs.create({url: 'https://www.example.com'});
  const tabId = tab.id;
  if (!tab.url) await onTabUrlUpdated(tabId);
  const results = await chrome.scripting.executeScript({
    target: {tabId},
    files: ['content.js'],
  });
  chrome.tabs.sendMessage(tabId, {msg: 'analysis background'}, res => {
    port.postMessage(res);
    chrome.tabs.remove(tabId);
  });
})();

function onTabUrlUpdated(tabId) {
  return new Promise((resolve, reject) => {
    const onUpdated = (id, info) => id === tabId && info.url && done(true);
    const onRemoved = id => id === tabId && done(false);
    chrome.tabs.onUpdated.addListener(onUpdated);
    chrome.tabs.onRemoved.addListener(onRemoved);
    function done(ok) {
      chrome.tabs.onUpdated.removeListener(onUpdated);
      chrome.tabs.onRemoved.removeListener(onRemoved);
      (ok ? resolve : reject)();
    }
  });
}
Related