Spurious
Spurious

Reputation: 1995

Chrome Extension with injected Javascript - Cannot read properties of undefined (reading 'sendMessage')

I have a script that I inject in the DOM and I want to send messages to my service worker in the background. I am getting an error and I don't understand why.

Here is my background.js file:

chrome.runtime.onMessage.addListener((req, sender, sendRes) => {
  console.log('this has worked', req, sender, sendRes('this worked'));
  return true;
});

Here is my inject.js file that injects the injected.js (see below) code:

const s = document.createElement('script');
s.src = chrome.runtime.getURL('injected.js');
s.onload = function () {
  this.remove();
};
(document.head || document.documentElement).appendChild(s);

injected.js:

console.log('fetch interceptor started');
const { fetch: origFetch } = window;
chrome.runtime.sendMessage({ works: 'This worked at least' }, (res) => console.log(res)); // Error is thrown immediately
window.fetch = async (...args) => {
  const response = await origFetch(...args);

  const url = new URL(args[0].url);
  //   sendMessageToBackground({ pathname, ...url.searchParams }); // not in use because it throws error at the top already
  response
    .clone()
    .json()
    .then(async (body) => await sendMessageToBackground({ pathname, body }))
    .catch((err) => console.error(err));

  return response;
};

async function sendMessageToBackground(msg) {
  const res = await chrome.runtime.sendMessage(msg);
  console.log('result message', res);
  console.log('msg', msg);
}

manifest.json in case required:

{
...
"permissions": ["storage", "activeTab", "scripting", "webRequest"],
  "host_permissions": ["https://REDACTED.com/*"],
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "content_scripts": [
    {
      "matches": ["https://REDACTED.com/*"],
      "run_at": "document_start",
      "js": ["inject.js"]
    }
  ],
  "web_accessible_resources": [{ "resources": ["injected.js"], "matches": ["https://REDACTED.com/*"] }],
...
}

Upvotes: 1

Views: 1178

Answers (1)

syncmate
syncmate

Reputation: 160

By injecting a content script declaratively or in a programmed way through the methods allowed by the "scripting" and\or "tabs" permissions, you bring to the web page a set of objects belonging to the world of extensions to which you would normally not be able to access.

Therefore, the inject.js script will be able to access these objects (in your case chrome.runtime), while the injectED.js script will not.

I don't know what purpose your Chinese box system has, but I would try to skip inject.js and inject injectED.js declaratively.

For the await speech together with .then, in my opinion there are no contraindications (at least at first sight). I've written routines before where I use this mix and never had a issue.

Upvotes: 2

Related Questions