Reactjs Chrome扩展UI页面和内容脚本之间的通信问题
这里没有问题: 上周,我编写了一个非常基本的Chrome扩展,其中popup.js以以下方式向content.js脚本发送消息(也许这不是最好的方式,但重要的是它工作了。为什么重要?请耐心等待我…) 在popup.js中Reactjs Chrome扩展UI页面和内容脚本之间的通信问题,reactjs,webpack,google-chrome-extension,Reactjs,Webpack,Google Chrome Extension,这里没有问题: 上周,我编写了一个非常基本的Chrome扩展,其中popup.js以以下方式向content.js脚本发送消息(也许这不是最好的方式,但重要的是它工作了。为什么重要?请耐心等待我…) 在popup.js中 someButton.addEventListener('click', (event) => { chrome.tabs.executeScript(null, { file: 'src/content.js', }, () =>
someButton.addEventListener('click', (event) => {
chrome.tabs.executeScript(null, {
file: 'src/content.js',
}, () => {
connect();
});
});
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, {
type: "info",
someValue: value
});
});
后来:
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
}
});
});
}
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.type == "info"){
sendResponse({ message: "some answer" })
}
return true;
})
这是可行的,但我相信这不是最好的办法。从上周开始,我读了很多书,我知道我相信正确的方法应该是这样的:
关于popup.js
someButton.addEventListener('click', (event) => {
chrome.tabs.executeScript(null, {
file: 'src/content.js',
}, () => {
connect();
});
});
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
chrome.tabs.sendMessage(tabs[0].id, {
type: "info",
someValue: value
});
});
在content.js中
if (!chrome.runtime.onConnect.hasListeners()) {
chrome.runtime.onConnect.addListener((port) => {
port.onMessage.addListener((msg) => {
if (msg && msg.type == "info") {
// do some stuff
}
});
});
}
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.type == "info"){
sendResponse({ message: "some answer" })
}
return true;
})
但在我的新版本中,这不起作用,即使每个教程和文档都说应该这样做。我没有收到任何错误,简单地说,添加到侦听器的函数从未执行过
我怀疑这可能与我现在使用React和Webpack有关,也许Webpack做了一些奇怪的事情
mymanifest.json的一个片段
"background": {
"persistent": false,
"scripts": ["background.bundle.js"]
},
"content_scripts": [{
"matches": ["<all_urls>"],
"js": ["content.bundle.js"]
}],
“背景”:{
“坚持”:假,
“脚本”:[“background.bundle.js”]
},
“内容脚本”:[{
“匹配项”:[“”],
“js”:[“content.bundle.js”]
}],
也许问题是我在用bundle指定内容和背景?不确定,我唯一知道的是,根据我的理解,这应该是有效的,但事实并非如此
我错过了什么
PS:我应该补充一点,我一直在调试,我发现内容文件正在执行,发送消息的代码也已经执行。这就像addListener没有正确添加,或者由于某种原因从未收到消息一样。当您在manifest.json中声明
content\u scripts
时,默认情况下它在DOMContentLoaded
和load
事件之间运行,因此如果您在仍在加载的复杂页面上打开弹出窗口,将没有内容脚本来接收消息
您可以指定在页面仍然为空时使内容脚本在“开始”运行,DOM将只有文档。documentElement
对于
节点,将没有
或
请注意,manifest.json中声明的内容脚本始终在每个匹配页面中运行,因此如果您的扩展仅在单击弹出窗口后才需要内容脚本,这将非常糟糕,因为您浪费了99.999%的资源,并且实际上需要广泛的主机权限。在这种情况下,您应该1)从manifest.json中删除
content\u脚本
,2)在“权限”中添加activeTab
并删除任何广泛的主机权限,例如
或*://*/*
或http://*/*
,3)像以前一样使用executeScript和HasListener。一如既往地非常感谢您,你的回答很清楚。但遗憾的是,我仍然有些怀疑。例如,当我使用executeScript时,我发送了文件名,但是对于webpack,应该使用包名吗?类似于chrome.tabs.executeScript(null,{file:“content.bundle.js”,},()=>{connect();})代码>很抱歉代码的格式设置,注释的灵活性较低,这对网页没有帮助。这取决于你的网页配置,所以试着问一个新问题。