reactjs - Chrome 扩展 UI 页面和内容脚本之间的通信问题
问题描述
这里的菜鸟问题:
上周我写了一个非常基本的 Chrome 扩展程序,其中一个 popup.js 向 content.js 脚本发送一条消息,方式如下(也许这不是最好的方式,但重要的是它有效。为什么这很重要吗?忍受我......)
在 popup.js
someButton.addEventListener('click', (event) => {
chrome.tabs.executeScript(null, {
file: 'src/content.js',
}, () => {
connect();
});
});
然后:
function connect() {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
const port = chrome.tabs.connect(tabs[0].id);
port.postMessage({ type: 'info', data: someValue });
})
}
在 content.js
if (!chrome.runtime.onConnect.hasListeners()) {
chrome.runtime.onConnect.addListener((port) => {
port.onMessage.addListener((msg) => {
if (msg && msg.type == "info") {
// do some stuff
}
});
});
}
这行得通,但我相信这不是最好的方法。自上周以来,我一直在阅读更多内容,并且知道我相信正确的方法应该是这样的:
在 popup.js 上
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, {
type: "info",
someValue: value
});
});
在 content.js 中
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.type == "info"){
sendResponse({ message: "some answer" })
}
return true;
})
但是在我的新版本中,这不起作用,即使每个教程和文档都说应该这样做。我没有收到任何错误,只是添加到侦听器的函数永远不会执行。
我怀疑这可能与我现在使用 React 和 Webpack 有关,也许 Webpack 正在做一些奇怪的事情?
我的 manifest.json 的一个片段
"background": {
"persistent": false,
"scripts": ["background.bundle.js"]
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.bundle.js"]
}],
也许问题是我正在使用捆绑包指定内容和背景?不确定,我唯一知道的是,根据我的理解,这应该有效,但事实并非如此。
我错过了什么?
PS:我要补充一点,我一直在调试,我发现内容文件正在执行,并且发送消息的那段代码也已执行。就像 addListener 没有正确添加,或者由于某种原因从未收到消息。
解决方案
当您content_scripts
在 manifest.json 中声明时,它默认在DOMContentLoaded
和load
事件之间运行,因此如果您在仍在加载的复杂页面上打开弹出窗口,则不会有内容脚本来接收消息。
您可以指定"run_at": "document_start"document.documentElement
使内容脚本在页面仍然为空时在 "start" 处运行,DOM 将只有<html>
节点,不会有<head>
or <body>
。
请注意,在 manifest.json 中声明的内容脚本始终在每个匹配页面中运行,因此如果您的扩展程序仅在单击弹出窗口后才需要内容脚本,这将非常非常糟糕,因为您浪费了 99.999% 的时间和实际上需要广泛的主机权限。在这种情况下,您应该 1)content_scripts
从 manifest.json 中删除,2) 添加activeTab
“权限”并删除任何广泛的主机权限,例如<all_urls>
or*://*/*
或http://*/*
3) 像以前一样使用 executeScript 和 hasListeners。
推荐阅读
- forms - 如何设置实体、表格和 TWIG 关于带小数的数字
- react-native - 在调试中工作,但在发布中不工作 | 世博会 | react-native-unimodules
- php - 带有 Wordpress 的 XAMPP 运行速度太慢
- outlook - 当在 VSTO 加载项中调用 MailItem 的 SaveChanges 时,SelectionChanged 会在 Outlook 中触发
- firebase - 如何在组和区域中部署单个 Firebase Cloud Function?
- javascript - 单击鼠标悬停以应用样式
- python - 在 Python 中预测差分进化的并行性能
- elixir - 是否可以使用 Ecto.Migrator 模拟“ecto.load”任务来发布 Elixir?
- c# - 如何使用 C# 表单应用程序使雷达设计看起来更有创意?
- python - 如何计算每个纬度/经度方格的 m2 大小