调用chrome.runtime.sendMessage()时出现“扩展上下文无效”错误

时间:2019-02-23 00:45:42

标签: google-chrome-extension content-script

我在Chrome扩展程序中有一个内容脚本,用于传递消息。每当内容脚本调用时,

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

它引发错误:

Uncaught Error: Extension context invalidated.

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

它并没有持续发生。实际上,很难复制。如果我只是在后台将页面打开一段时间,似乎会发生。


另一个线索:我编写了许多带有内容脚本的Chrome扩展程序,这些脚本可以传递消息,而我以前从未见过此错误。主要区别在于此内容脚本是由后台页面使用

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

使用executeScript而不是清单文件会以某种方式更改内容脚本的生命周期吗?

1 个答案:

答案 0 :(得分:1)

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

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

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