Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

chrome.scripting.executeScript not working in my manifest v3 Chrome Extension

I have an extension where I call

function doScript(window) {
  chrome.scripting.executeScript(
    {
      target: {tabId: window.tabs[0].id},
      files: ['myscript.js'],
    });
}

myscript.js simply has

alert("Made it")

but I get no alert in my tab.

If I change the tabId to something random like 123

  chrome.scripting.executeScript(
    {
      target: {tabId: 123},
      files: ['myscript.js'],
    });

then I get an error "Unchecked runtime.lastError: No tab with id: 123"

So it looks like my tabId is right, but for some reason myscript.js is not triggering an alert.

If I mess up the script name like this

  chrome.scripting.executeScript(
    {
      target: {tabId: window.tabs[0].id}},
      files: ['ttttttttttt.js'],
    });

I get "runtime.lastError: Could not load file: 'ttttttttttt.js'."

I tried looking through the console logs and the only thing I see is this error upon clicking but it looks like a red herring.

"Unchecked runtime.lastError: Cannot access contents of url "". Extension manifest must request permission to access this host." https://github.com/GoogleChrome/web-vitals-extension/issues/54

Here is my manifest

{
    "manifest_version": 3,
    "name": "pokemon bokemon",
    "description": "",
    "version": "0.3.0",
    "action": {
        "default_popup": "popup.html"
    },
    "icons": {
        "16": "icon16.png",
        "32": "icon32.png"
    },
    "permissions": [
        "tabs",
        "storage",
        "scripting",
        "activeTab",
        "cookies"
    ],
    "host_permissions": [
        "*://*/*",
        "<all_urls>"
    ],
    "options_page": "options.html"
}

EDIT: Apparently it's a bug in chrome/manifest v3. Opened a bug here: https://bugs.chromium.org/p/chromium/issues/detail?id=1191971

like image 515
stacksonstacks Avatar asked Mar 23 '21 23:03

stacksonstacks


People also ask

What is chrome scripting?

Chrome Scripting API is one of the latest features introduced to the Chrome browser extension platform. It is a part of the Manifest V3 update and capable of injecting JavaScript and CSS into websites using Chrome.

Can't establish connection receiving end does not exist Chrome extension?

receiving end does not exist error is fixed by disabling specific Chrome extensions.

What's new with Chrome's extension platform in Manifest V3?

Manifest V3 introduces a number of changes to Chrome's extension platform. In this post, we'll be exploring the motivations and changes introduced by one of the more notable changes: the introduction of the chrome.scripting API. # What is chrome.scripting?

How to execute a script in different contexts in chrome?

Use the chrome.scripting API to execute script in different contexts. In order to use the chrome.scripting API, you need to specify a "manifest_version" of 3 or higher and include the "scripting" permission in your manifest file.

What is chrome scripting?

# What is chrome.scripting? As the name might suggest, chrome.scripting is a new namespace introduced in Manifest V3 responsible for script and style injection capabilities. Developers that have created Chrome extensions in the past may be familiar with Manifest V2 methods on the Tabs API like chrome.tabs.executeScript and chrome.tabs.insertCSS.

Can dynamic content scripts be used with Chrome extensions?

Dynamic content scripts support has been a long-standing feature request in Chromium. Today, Manifest V2 and V3 Chrome extensions can only statically declare content scripts in their manifest.json file; the platform doesn't provide a way to register new content scripts, tweak content script registration, or unregister content scripts at runtime.


1 Answers

I also encountered the same problem, and I share my experience as follows.

If you use chrome.windows.create to create a new tab(panel, popup,...) and then call chrome.scripting.executeScript in the new one. Unfortunately, it will not work.

for example

// popup.js
const targetURL = 'templates/main.html'
chrome.windows.create(
  {
    focused: true,
    url: targetURL,
    type: 'popup',
  },
  (subWindow) => {
  }
)
// But you can put the ``chrome.scripting.executeScript``here, which will be fine.
chrome.scripting.executeScript({})

does not work in templates/main.html

<script>
// templates/main.html

chrome.tabs.query({active: true, currentWindow: true}).then(([tab]) => {
  chrome.scripting.executeScript(
    {
      target: {tabId: tab.id},
      files: ['myscript.js'],
      // function: () => {}, // files or function, both do not work.
    })
})
</script>

If you want to communicate with each other, you can try.

chrome.tabs.sendMessage(myTabID, {event: 'myTest'}, ({msg, other})=>{
  console.log(msg) // hello
  console.log(other) // test
})

chrome.runtime.onMessage.addListener((media, sender, sendResponse) => {
  if (media.event === 'myTest') {
    sendResponse({msg:"hello", other:"test"})
  }
})

Supplement for sendMessage & onMessage

  • chrome.tabs.sendMessage
  • chrome.runtime.onMessage.addListener

If you need a working example, you can refer to one of my repositories.

https://github.com/CarsonSlovoka/chrome/tree/7f1e731/tutorials/extensions/tabs-info

enter image description here

Click the button, and the following log will show some information from the tabs.

Suggested order for your reading:

two parts

  1. sendMessage

    1. manifest.json -> popup.html
    2. popup.html -> popup.js
    3. popup.js -> main.html
    4. main.html -> main.js
    5. main.js: chrome.tabs.sendMessage 👈
  2. onMessage

    • manifest.json content_scripts: scripting/thumbnail.js
    • thumbnail.js: onMessage 👈
like image 152
Carson Avatar answered Oct 26 '22 16:10

Carson