调用 chrome.runtime.sendMessage() 时"Extension context invalidated"错误



我在传递消息的chrome扩展程序中有一个内容脚本。每隔一段时间,当内容脚本调用

chrome.runtime.sendMessage({
  message: 'hello',
});

它引发错误:

Uncaught Error: Extension context invalidated.

此错误是什么意思?我找不到任何文档。

它不会始终如一。实际上,很难复制。如果我只是在后台打开一段时间,似乎会发生。


另一个线索:我已经写了许多传递消息的内容脚本的Chrome扩展程序,但我以前从未见过此错误。主要区别在于,此内容脚本由背景页面使用

注入
chrome.tabs.executeScript({
  file: 'contentScript.js',
});

是否使用executeScript代替清单文件以某种方式更改内容脚本的生命周期?

这肯定与在内容和背景脚本之间连接的中间丢失的消息侦听器有关。

我一直在扩展中使用这种方法,因此我有一个可以在后台和内容脚本中使用的模块。

messenger.js

const context = (typeof browser.runtime.getBackgroundPage !== 'function') ? 'content' : 'background'
chrome.runtime.onConnect.addListener(function (port) {
  port.onMessage.addListener(function (request) {
    try {
      const object = window.myGlobalModule[request.class]
      object[request.action].apply(module, request.data)
    } catch () {
      console.error(error)
    }
  })
})
export function postMessage (request) {
  if (context === 'content') {
    const port = chrome.runtime.connect()
    port.postMessage(request)
  }
  if (context === 'background') {
    if (request.allTabs) {
      chrome.tabs.query({}, (tabs) => {
        for (let i = 0; i < tabs.length; ++i) {
          const port = chrome.tabs.connect(tabs[i].id)
          port.postMessage(request)
        }
      })
    } else if (request.tabId) {
      const port = chrome.tabs.connect(request.tabId)
      port.postMessage(request)
    } else if (request.tabDomain) {
      const url = `*://*.${request.tabDomain}/*`
      chrome.tabs.query({ url }, (tabs) => {
        tabs.forEach((tab) => {
          const port = chrome.tabs.connect(tab.id)
          port.postMessage(request)
        })
      })
    } else {
      query({ active: true, currentWindow: true }, (tabs) => {
        const port = chrome.tabs.connect(tabs[0].id)
        port.postMessage(request)
      })
    }
  }
}
export default { postMessage }

现在,您只需要在内容和背景脚本中导入此模块即可。如果要发送消息,只需做:

messenger.postMessage({
   class: 'someClassInMyGlobalModuçe',
   action: 'someMethodOfThatClass',
   data: [] // any data type you want to send
})

您可以指定是否要发送到allTabs: true,特定域tabDomain: 'google.com'或单个选项卡tabId: 12

相关内容

最新更新