Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs Chrome扩展UI页面和内容脚本之间的通信问题_Reactjs_Webpack_Google Chrome Extension - Fatal编程技术网

Reactjs Chrome扩展UI页面和内容脚本之间的通信问题

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', }, () =>

这里没有问题:

上周,我编写了一个非常基本的Chrome扩展,其中popup.js以以下方式向content.js脚本发送消息(也许这不是最好的方式,但重要的是它工作了。为什么重要?请耐心等待我…)

在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
      });
    });
后来:

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();})很抱歉代码的格式设置,注释的灵活性较低,这对网页没有帮助。这取决于你的网页配置,所以试着问一个新问题。