简体   繁体   中英

Pass message to Chrome extension content script without specifying it as a background script

I'm trying to add a feature to the Chrome context menu to add a todo item from selected text. I pass the selected text from a context menu in background.js like so:

function onClickHandler(info, tab) {
  chrome.extension.sendMessage(info.selectionText, function(){});
}

chrome.contextMenus.onClicked.addListener(onClickHandler);

chrome.runtime.onInstalled.addListener(function() {

  chrome.contextMenus.create({"title": "Add: %s", "contexts":["selection"]});

});

And then listen for the message in an app.js content script:

chrome.extension.onMessage.addListener(function(task, sender, sendResponse) {
  Task.setNewTask(task); // Saves the task in storage
});

The message is received correctly when my extension is open in a tab, but doesn't work when it is closed. This is because I don't set app.js as a background script in my manifest.json :

"permissions": [
    "storage",
    "contextMenus",
    "tabs",
    "notifications"
],

"background": {
  "scripts": ["background.js"]
}

The reason I don't include app.js as a background script is because it includes the rest of my app's code, which generates errors when tried to run in the background without a DOM.

Unfortunately I can't easily do the storage in the background.js file because I need access to the function Task.setNewTask which is in my content script.

My app has various methods of storing data depending on the environment – there would be a lot of duplication if I had to put this logic in background.js .

I've tried including my app as a background page:

"background": {
  "page": "index.html"
},

And then including both scripts at the bottom of the page:

  <script src="background.js"></script>
  <script src="js/app.js"></script>
</body>

But my app still won't add new tasks in the background.

Is there a way to:

  • Keep background.js as simple as possible,
  • Not include app.js as a background script,
  • Still receive a message when app.js is not in the background?

Oh dear. Where did you find the base code you're modifying?

chrome.extension.sendMessage / chrome.extension.onMessage are deprecated to the point of not even being in the documentation anymore.

But even if you change them to the proper chrome.runtime equivalents, it's still the wrong function to communicate with a content script.

  1. Your original code fails, since chrome.runtime.sendMessage (and deprecated chrome.extension equivalent) are sending only to extension pages (eg to the chrome-extension://yourid/ origin), not to content scripts.

  2. Your modified code fails, since messaging never sends a message to the same JS context it's running from.

What you need is chrome.tabs.sendMessage function, that allows you to specify the tab where your context script is. If you want to send it to the current tab, it's passed as a parameter to the onClicked listener.

function onClickHandler(info, tab) {
  chrome.tabs.sendMessage(tab.id, info.selectionText);
}

On the context script side, don't forget to change to chrome.runtime :

chrome.runtime.onMessage.addListener(function(task, sender, sendResponse) {
  Task.setNewTask(task); // Saves the task in storage
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM