我在传递消息的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
。