【问题标题】:Send message to background.js from options.js in Chrome ExtensionSend message to background.js from options.js in Chrome Extension
【发布时间】:2022-12-19 04:07:43
【问题描述】:

I can find plenty of questions for sending a message from Bbackground to content scripts or from popup to background scripts, but I can't find any on how to send a message from options.js (triggered from my options page) to background.js for my Chrome extension

manifest.js

{
  ...
  "manifest_version": 3,
  "permissions": [
    "alarms",
    "contextMenus",
    "notifications",
    "storage"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html"
  },
  "options_page": "options.html",
  "icons": {
    "48": "/assets/icons/icon-48.png",
    "128": "/assets/icons/icon-128.png"
  }
}

Code in options.js

// Save options
document.querySelector('#save').addEventListener('click', ()=> {
  // Check for selected regions
  let selectedRegions = [];
  regionChecks.forEach(elm => {
    if (elm.checked)
      selectedRegions.push(elm.id.replace('region-', ''))
  });
  // Save selections
  chrome.storage.sync.set({ 'regions': selectedRegions });

  // Check for refresh period
  let refreshPeriod = document.querySelector('#refresh');
  if (refreshPeriod) {
    refreshPeriod = parseInt(refreshPeriod.value);
    if (refreshPeriod === NaN) {
      refreshPeriod = 5;
    } else if(refreshPeriod < 2) {
      refreshPeriod = 2;
    } else if (refreshPeriod > 120) {
      refreshPeriod = 120;
    }
    // Save period
    chrome.storage.sync.set({ 'refresh': refreshPeriod });
  }

  // Loop through features and remove if region gone
  chrome.storage.local.get(['features'], featuresData => {
    let featureCount = 0;
    if (featuresData.features) {
      featureSet = featuresData.features;
      Object.keys(featureSet).forEach(key => {
        if (!selectedRegions.includes(featureSet[key].Region)) {
          delete featureSet[key];
        } else if (featureSet[key].Status !== "read") {
          featureCount = featureCount + 1;
        }
      });
      // Update features data
      chrome.storage.local.set({ 'features': featureSet });
      // Update the badge
      if (featureCount > 0) {
        chrome.action.setBadgeText({ text: featureCount.toString() });
      } else {
        chrome.action.setBadgeText({ text: '' });
      }
    }
  });

  // Trigger an update
  chrome.runtime.sendMessage('', {
    type: 'update'
  });

  // Close the options page
  close();
});

Code in background.js

// Listen for messages
chrome.runtime.onMessage.addListener(data => {
  console.log(data);
  if (data.type === 'update') {
    scheduleRequest();
  }
});

But nothing is happening

I've tried using tabs.sendMessage, but even if I put tabs in permissions it tells me that it isn't defined when I add it to the function chrome.tabs.sendMessage(tabs[0].id, {...

【问题讨论】:

  • 1) Remove '', from sendMessage. 2) How to see background.js console?, 3) Maybe move close() into the callback of sendMessage.
  • @wOxxOm thanks, this did it! :D If you want to post 1 and 3 as an answer I'll accept it

标签: javascript google-chrome-extension


【解决方案1】:

My test results contradict your claim.

manifest.json

{
  "manifest_version": 3,
  "name": "hoge",
  "version": "1.0",
  "background": {
    "service_worker": "background.js"
  },
  "options_page": "options.html"
}

background.js

// Listen for messages
chrome.runtime.onMessage.addListener(data => {
  console.log(data);
  if (data.type === 'update') {
    console.log("hoge")
    //    scheduleRequest();
  }
});

options.js

// Trigger an update
chrome.runtime.sendMessage('', {
  type: 'update'
});

options.html

<html>
<body>
  options page
  <script src="options.js"></script>
</body>
</html>

【讨论】:

  • Sorry, I just realised I forgot something vital in my options.js file example. That code is only running after I click save. I've just tested my code again and it's not showing a console still.
  • I think you should post all files.
  • Prove that chrome.runtime.sendMessage in options.js is called.
  • I've posted my full code in that function. Everything else in that function is working just fine, it's just not triggering anything in my background.js. Everything else in my background.js file is also running with no problems. I just seem to be having an issue with the sendMessage
  • Set a breakpoint on the line calling chrome.runtime.sendMessage() in options.js and make sure it breaks.
【解决方案2】:

After some input from @woxxom and @Norio, and a little bit more troubleshooting, this is how I managed to get it to work

option.js:

// Trigger an update
chrome.runtime.sendMessage({ type: 'update' }, result => {
  // Close the options page
  close();
});

I had to move the close(); event into the return function so it didn't prematurely close off the code. I also had to have a paramter in the return function for some reason otherwise it wouldn't run with an empty arrow function.

background.js:

// Listen for messages
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'update') {
    startRequest(true).then(sendResponse);
    return true;
  }
});

My function to be triggered in the background.js file was already an async promise function, so I had to add a .then() for the onMessage response function to trigger once it had run. It also wouldn't work without having return true; in there.

【讨论】:

    猜你喜欢
    • 2022-12-02
    • 2022-12-27
    • 2016-04-28
    • 1970-01-01
    • 2022-12-02
    • 2022-12-02
    • 2013-06-22
    • 1970-01-01
    • 2012-09-05
    相关资源
    最近更新 更多