首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >调用chrome.runtime.sendMessage()时出现的“扩展上下文无效”错误

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

Stack Overflow用户
提问于 2019-02-23 00:45:41
回答 1查看 5.5K关注 0票数 6

我在Chrome扩展中有一个内容脚本来传递消息。经常,当内容脚本调用

代码语言:javascript
运行
复制
chrome.runtime.sendMessage({
  message: 'hello',
});

它抛出一个错误:

代码语言:javascript
运行
复制
Uncaught Error: Extension context invalidated.

这个错误意味着什么?,我找不到它的任何文档。

事情不会一拖再拖。事实上,这是很难复制。如果我只是在后台把页面打开一段时间,似乎就会发生。

另一条线索:我编写了许多Chrome扩展,其中包含传递消息的内容脚本,而且我以前从未见过这个错误。主要区别在于,这个内容脚本是由后台页面注入的,使用

代码语言:javascript
运行
复制
chrome.tabs.executeScript({
  file: 'contentScript.js',
});

使用executeScript而不是清单文件会改变内容脚本的生命周期吗?

EN

回答 1

Stack Overflow用户

发布于 2019-02-23 01:27:55

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

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

messenger.js

代码语言:javascript
运行
复制
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 }

现在,您只需要在内容和后台脚本中导入这个模块。如果您想发送信息,只需:

代码语言:javascript
运行
复制
messenger.postMessage({
   class: 'someClassInMyGlobalModuçe',
   action: 'someMethodOfThatClass',
   data: [] // any data type you want to send
})

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54837077

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档