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
- Site permissions should be added to
host_permissions
, notpermissions
, more info. - 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.
(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
How to Calculate How Many Seconds Between Two Dates
How to Send the "&" (Ampersand) Character via Ajax
Escaping Backslash in String - JavaScript
How to Write Regex to Validate Dates
Add Commas to a Number in Jquery
Rails 5: How to Use $(Document).Ready() with Turbo-Links
In Angular, How to Determine the Active Route
Why and When to Use Default Export Over Named Exports in Es6 Modules
Why Use Redux Over Facebook Flux
How Does Trello Access the User's Clipboard
Does It Make Sense to Use Require.Js with Angular.Js
Differencebetween JavaScript and Ecmascript
JavaScript Listener, "Keypress" Doesn't Detect Backspace