Unchecked Runtime.Lasterror While Running Tabs.Executescript

Unchecked runtime.lastError while running tabs.executeScript?

"Check" runtime.lastError by "reading" it in the callback.


Code

chrome.tabs.executeScript(tabId, {
//..
}, _=>chrome.runtime.lastError /* "check" error */)

Eg

Show it via..

chrome.tabs.executeScript(tabId, {
//..
}, _=>{
let e = chrome.runtime.lastError;
if(e !== undefined){
console.log(tabId, _, e);
}
});

Unchecked runtime.lastError: Cannot access contents of url. But I dont need to access content of that URL

The problem is that executeScript without a tab id (null in your code) runs in the active tab (aka "currently focused" tab) but navigation can also occur in inactive tabs.

You need to use details.tabId in executeScript to run it in the tab where navigation occurred:

chrome.tabs.executeScript(details.tabId, { file: "content.js" });

Further optimizations:

  • It might be more efficient to use simple messaging instead of re-injecting.

  • The webNavigation event is triggered in iframes too so check details.frameId to skip them.

  • Use URL filters to limit webNavigation events:

    chrome.webNavigation.onHistoryStateUpdated.addListener(details => {
    if (!details.frameId) {
    chrome.tabs.executeScript(details.tabId, {file: 'content.js'});
    }
    }, {
    url: [
    {hostEquals: 'youtu.be'},
    {hostEquals: 'www.youtube.com', pathPrefix: '/watch'},
    ],
    });

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

  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)();
}
});
}

Unchecked runtime.lastError while running tabs.executeScript: Cannot access contents of url data:text/html,chromewebdata

Indeed, the "Offline" page, or any other error page shown is treated as a Chrome internal page instead of its "original" URL. As such, you can't inject into such pages to change them for security reasons. Imagine for a moment that an extension would be able to interact with SSL warning pages - you really, really don't want that.

If your goal is to provide some sort of alternative error page, you need to hook a listener for such navigation errors and redirect to your own page.

I would recommend looking at webNavigation and webRequest API.

Chrome Extension gives two errors: Uncaught TypeError and Unchecked runtime.lastError

The background script page is an invisible hidden page, so running visible scripts like app.js or popup.js there is meaningless. Remove background section from manifest.json and rename your background.html to popup.html both on the disk and in manifest.json.

manifest.json:

{
"name": "Gina's Bakery Order",
"version": "1.0",
"permissions": ["activeTab", "declarativeContent", "storage"],
"browser_action": {"default_popup": "popup.html"},
"manifest_version": 2
}

Content scripts run only when the page loads, so if you just reloaded or installed/updated the extension without reloading the tab, the content scripts won't run there.

Although you can inject them explicitly, it's much better to switch to programmatic injection on demand (use executeScript instead of content_scripts) because you can do it without requiring any host permissions when installing the extension.

popup.js:

const textArea = document.getElementById('productList');
const btn = document.getElementById('populateBtn');
btn.onclick = () => {
const data = textArea.value.replace(/\t/g, '').split('\n');
chrome.tabs.query({active: true, currentWindow: true}, ([tab]) => {
chrome.tabs.sendMessage(tab.id, {data}, () => {
if (chrome.runtime.lastError) {
chrome.tabs.executeScript({file: 'inject.js'}, () => {
chrome.tabs.sendMessage(tab.id, {data});
});
}
});
});
};

Since you're not using the response in sendMessage, don't send it in the first place, i.e. remove sendResponse({result: "ok"}); return true; from inject.js.



Related Topics



Leave a reply



Submit