Manifest V3: Unable to inject script to the locally opened file

1,252 views
Skip to first unread message

Oleksandr Nemchenko

unread,
Oct 5, 2022, 3:52:11 AM10/5/22
to Chromium Extensions

I am unable to inject script to the locally opened web page due to the permission error. It's strange because I have requested already permission for "<all_urls">.

This is small extension with service worker that will open page, injest script to this page and interract with it.

Here is my manifest.json:

{ "name": "Test",
"version": "0.1",
"incognito": "split",
"manifest_version": 3,
"background": { "service_worker": "test.js", "type": "module" },
"permissions": [ "activeTab", "scripting", "tabs" ],
 "host_permissions": [ "*://*/*", "<all_urls>" ] }

Here is my service worker script test.js:

"use strict"; 
 async function Startup() {
 const tab = await chrome.tabs.create({url: chrome.runtime.getURL("test.html"), active: false});
let curPage = tab.id;
console.log(`Page opened`);
await new Promise(resolve => {
chrome.scripting.executeScript({
  files: [`testInjection.js`], target: { tabId: curPage }, },
  () => { resolve(true); }); });
console.log(`Script injected`);
}
Startup();

Here is my script to be injected testInjection.js:

"use strict";
function SendMainScriptMessage(packet, processResponse) {  chrome.runtime.sendMessage(packet);
}

async function InjectedCodeListener(request, sender, sendResponse) { SendMainScriptMessage({id: "Started"});
if (request.id == "Init") {
  report.innerText = request.text;
  SendMainScriptMessage({id: "Initialized"});
}
}

chrome.runtime.onMessage.addListener(InjectedCodeListener);

Finally, here is my web page test.html:

<html> <body> <p id="report"></p> <button id="click">Open</button> </body> </html>

Here is Console output:

Page opened

Unchecked runtime.lastError: Cannot access contents of url "chrome-extension://lokbdjdhbldkdmccaekalojjmjejonkg/test.html". Extension manifest must request permission to access this host.

Script injected

Here is my environment:

  • Windows 10 x64
  • Chrome Version 106.0.5249.91 (Official Build) (64-bit)

wOxxOm

unread,
Oct 5, 2022, 4:51:09 AM10/5/22
to Chromium Extensions, a...@nemchenko.net
executeScript is only for web pages, just like content_scripts, but you open an extension page - it has a chrome-extension:// URL.

The solution is to use standard DOM methods to run scripts inside i.e. <script src="script.js"><?script>

You can also create a DOM script on demand by using document.createElement and document.head.appendChild. You may want to do it for optional features.

wOxxOm

unread,
Oct 5, 2022, 4:51:40 AM10/5/22
to Chromium Extensions, wOxxOm, a...@nemchenko.net
Fixed the typo:

<script src="script.js"></script>

Oleksandr Nemchenko

unread,
Oct 5, 2022, 4:59:47 AM10/5/22
to Chromium Extensions, wOxxOm, Oleksandr Nemchenko
>The solution is to use standard DOM methods to run scripts inside i.e. <script src="script.js"><?script>
The problem is that I need to interract not only with my HTML page, but with any one. So, I can not directly change HTML code.

> You can also create a DOM script on demand by using document.createElement and document.head.appendChild. You may want to do it for optional features.
You mean that I can do it in my service worker for the tab? If "yes", could you provide, please, example how to do it?

среда, 5 октября 2022 г. в 11:51:09 UTC+3, wOxxOm:

wOxxOm

unread,
Oct 5, 2022, 5:42:18 AM10/5/22
to Chromium Extensions, a...@nemchenko.net, wOxxOm
>  So, I can not directly change HTML code.

It's your html file, you can edit it yourself manually and add  <script src="script.js"></script> then it'll just always run this script every time the page is opened.

> You mean that I can do it in my service worker for the tab?

No. It's your extension's page so you fully control what happens inside. Load script.js as shown above and do whatever you wants inside this page, like adding a listener for chrome.runtime.onMessage that can add new script elements dynamically via createElement and appendChild. BTW your background script is the service worker of this tab in ManifestV3, so you can even use navigator.serviceWorker in this page to communicate with your background script, which may be helpful to transfer super huge blobs/files instantly.

For example, your background script can check if the tab URL belongs to your extension and send a message using chrome.tabs.sendMessage from the service worker. It all depends on what your code does exactly, so a different approach may be better e.g. using chrome.storage + chrome.storage.onChanged. 
Reply all
Reply to author
Forward
0 new messages