admin管理员组

文章数量:1415421

I am attempting to display an alarm that pops up in my browser from background.js in Manifest v3. However, using the code implementation that is described in the Manifest v3 page does not produce an alarm.

Manifest.js:

{
  "name": "Focus-Bot",
  "description": "A bot meant to help you focus",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["storage", "activeTab", "scripting"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "/images/get_started16.png",
      "32": "/images/get_started32.png",
      "48": "/images/get_started48.png",
      "128": "/images/get_started128.png"
    }
  },
  "icons": {
    "16": "/images/get_started16.png",
    "32": "/images/get_started32.png",
    "48": "/images/get_started48.png",
    "128": "/images/get_started128.png"
  },
  "options_page": "options.html"
}

Background.js:

chrome.runtime.onInstalled.addListener(() => {
  chrome.scripting.executeScript({
    function: showAlert
  }) 
});

function showAlert(){
    alert('object input for later');
}

This version of background.js returns the following error

TypeError: Error in invocation of scripting.executeScript(scripting.ScriptInjection injection, optional function callback): Error at parameter 'injection': Missing required property 'target'.

The example code of a working Chrome Extension (the green background button) uses chrome.tabs in a popup.js file to get a target and inject javascript, but when background.js runs the same code like this:

Background.js (tabs):

chrome.runtime.onInstalled.addListener(() => {
  let [tab] = await chrome.tabs.query(queryOptions);
  console.log(tab)
  chrome.scripting.executeScript({
    function: showAlert
  }) 
});

function showAlert(){
    alert('object input for later');
}

Background.js seems to crash with "Service worker registration failed", with no error logs.

How do I display an alarm for the current active page from background.js?

I am attempting to display an alarm that pops up in my browser from background.js in Manifest v3. However, using the code implementation that is described in the Manifest v3 page does not produce an alarm.

Manifest.js:

{
  "name": "Focus-Bot",
  "description": "A bot meant to help you focus",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["storage", "activeTab", "scripting"],
  "action": {
    "default_popup": "popup.html",
    "default_icon": {
      "16": "/images/get_started16.png",
      "32": "/images/get_started32.png",
      "48": "/images/get_started48.png",
      "128": "/images/get_started128.png"
    }
  },
  "icons": {
    "16": "/images/get_started16.png",
    "32": "/images/get_started32.png",
    "48": "/images/get_started48.png",
    "128": "/images/get_started128.png"
  },
  "options_page": "options.html"
}

Background.js:

chrome.runtime.onInstalled.addListener(() => {
  chrome.scripting.executeScript({
    function: showAlert
  }) 
});

function showAlert(){
    alert('object input for later');
}

This version of background.js returns the following error

TypeError: Error in invocation of scripting.executeScript(scripting.ScriptInjection injection, optional function callback): Error at parameter 'injection': Missing required property 'target'.

The example code of a working Chrome Extension (the green background button) uses chrome.tabs in a popup.js file to get a target and inject javascript, but when background.js runs the same code like this:

Background.js (tabs):

chrome.runtime.onInstalled.addListener(() => {
  let [tab] = await chrome.tabs.query(queryOptions);
  console.log(tab)
  chrome.scripting.executeScript({
    function: showAlert
  }) 
});

function showAlert(){
    alert('object input for later');
}

Background.js seems to crash with "Service worker registration failed", with no error logs.

How do I display an alarm for the current active page from background.js?

Share Improve this question edited Jun 30, 2022 at 13:43 woxxom 74k14 gold badges156 silver badges160 bronze badges asked Apr 25, 2021 at 2:15 RedRoach51RedRoach51 1031 silver badge3 bronze badges 1
  • This question is similar to: `alert` not showing in ManifestV3 background service worker. If you believe it’s different, please edit the question, make it clear how it’s different and/or how the answers on that question are not helpful for your problem. – fregante Commented Feb 1 at 19:29
Add a ment  | 

2 Answers 2

Reset to default 5
  1. As the error message says you need to add target to executeScript's parameters. Always look up the exact usage of API methods in the documentation.

  2. Your code uses await but the function isn't declared with async which is a syntax error that causes the service worker to fail the registration. Currently ManifestV3 is riddled with bugs so it doesn't even show the cause of the failure so you'll have to use try/catch manually.

try {
  chrome.runtime.onInstalled.addListener(async () => {
    const [tab] = await chrome.tabs.query(queryOptions);
    chrome.scripting.executeScript({
      target: {tabId: tab.id},
      function: showAlert,
    });
  });
} catch (e) {
  console.error(e);
}

An arguably better/cleaner approach would be to use two files: the main code in bg.js and the try-catch wrapper in bg-loader.js that imports bg.js, see this example.

Note that the active tab may be un-injectable e.g. a default start page or a chrome:// page (settings, bookmarks, etc.) or a chrome-extension:// page. Instead you can open a small new window:

alert({html: 'Foo <b>bar</b><ul><li>bla<li>bla</ul>'})
  .then(() => console.log('alert closed'));

async function alert({
  html,
  title = chrome.runtime.getManifest().name,
  width = 300,
  height = 150,
  left,
  top,
}) {
  const w = left == null && top == null && await chrome.windows.getCurrent();
  const w2 = await chrome.windows.create({
    url: `data:text/html,<title>${title}</title>${html}`.replace(/#/g, '%23'),
    type: 'popup',
    left: left ?? Math.floor(w.left + (w.width - width) / 2),
    top: top ?? Math.floor(w.top + (w.height - height) / 2),
    height,
    width,
  });
  return new Promise(resolve => {
    chrome.windows.onRemoved.addListener(onRemoved, {windowTypes: ['popup']});
    function onRemoved(id) {
      if (id === w2.id) {
        chrome.windows.onRemoved.removeListener(onRemoved);
        resolve();
      }
    }
  });
}

The solution suggested by woxxom works in Chrome, but it doesn't work in Firefox because data: URLs are not supported there (as top-level location).

For this reason I published a package that uses the best available method to show messages to the user, whether it's via chrome.windows with data:, with external HTML or local HTML. It might also use action.openPopup when available

Repository: https://github./fregante/webext-alert

Notice that there's a clickable "OK" button just like for alert()

本文标签: javascriptHow to display an alert from backgroundjs in Manifest v3Stack Overflow