Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.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
Javascript Chrome扩展后台消息侦听器启动两次_Javascript_Ajax_Google Chrome Extension_Listener - Fatal编程技术网

Javascript Chrome扩展后台消息侦听器启动两次

Javascript Chrome扩展后台消息侦听器启动两次,javascript,ajax,google-chrome-extension,listener,Javascript,Ajax,Google Chrome Extension,Listener,我有一个chrome扩展,它的工作原理如下: Background: tab created; content script: askForPermission(); <-sends message asking for permission to start Bacground: go <- allows. content script: (content script logs, working as intended) Background listener: imDoneW

我有一个chrome扩展,它的工作原理如下:

Background: tab created;
content script: askForPermission(); <-sends message asking for permission to start
Bacground: go <- allows. 
content script: (content script logs, working as intended)
Background listener: imDoneWithFail;
Background update tab;
background listener: imDoneWithFail; <- shouldn't happen, doesn't look like it conten't script even started to work as it didn't ask for permission. Looks like listener is fired up twice...
Background update tab;
content script: askForPermission(); <-sends message asking for permission to start
Bacground: go <- allows. 
后台每隔几秒钟检查站点x是否有更改,如果有更改,后台将使用页面Y打开新选项卡,并执行一些页面自动化(在基于ajax的页面中填充调查)。页面自动化是通过内容脚本完成的。内容脚本需要请求后台允许才能开始工作。它通过发送消息并等待回复来实现这一点。当内容脚本完成它的工作时,它会向后台发送消息,其中包含成功与否的信息。当失败选项卡应更新为新链接时,成功选项卡应关闭。问题是,有时——并非总是——bacground的消息会出现两次。一次-当标签失败时,它的工作,第二次后,标签是用新的链接更新。我希望我能知道为什么

下面是脚本:

Background.js侦听器创建

function create_listerner(){
    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
            switch(request.greeting){
                case "site_opened":
                    if (sender.tab.id == tabId) {
                        sendResponse({
                            farewell : "go"
                        });
                    } else {
                        sendResponse({
                            farewell : "stop"
                        });
                    }
                    break;
                case "imDoneWithSuccess":
                    //update tab logic
                    break;
                case "imDoneWithFail":
                    //close tab logic
                    actNgo(url,arr);
                    break;
            }
        });
}
当用户从上下文菜单:background.js启动脚本时,侦听器调用一次

chrome.contextMenus.create({
    title : "Start",
    contexts : ["browser_action"],
    onclick : function () {
        create_listerner();
    }
});
function actNgo(url,arr){
    chrome.storage.local.set({
        array : arr,
        ndz : 1
    }, function () {
        chrome.tabs.update(
            tabId,
            {
                "url" : url,
                "active" : false
            }, function (tab) {
                console.log("tabId "+tabId);
            });
    });
}
选项卡更新看起来很简单:background.js

chrome.contextMenus.create({
    title : "Start",
    contexts : ["browser_action"],
    onclick : function () {
        create_listerner();
    }
});
function actNgo(url,arr){
    chrome.storage.local.set({
        array : arr,
        ndz : 1
    }, function () {
        chrome.tabs.update(
            tabId,
            {
                "url" : url,
                "active" : false
            }, function (tab) {
                console.log("tabId "+tabId);
            });
    });
}
内容脚本被注入网站,网站不会像基于ajax的那个样重新加载,即使在不满足适当条件的情况下无法发送消息

content.js

function SR(st) {
    var status ;
    if(st){
        status = "imDoneWithSuccess";
    } else {
        status = "imDoneWithFail";
    }
    chrome.runtime.sendMessage({
        greeting : status 
    }, function (response) {
    });
}
内容脚本应仅在bacground.js打开的选项卡上工作

function askForPermission() {
    chrome.runtime.sendMessage({
        greeting : "site_opened"
    }, function (response) {
        if (response.farewell == 'go') {
            start();
        } else {
            console.log("bad tab");
        }
    });
}
再说一次,他们不可能自己点火

日志文件如下所示:

Background: tab created;
content script: askForPermission(); <-sends message asking for permission to start
Bacground: go <- allows. 
content script: (content script logs, working as intended)
Background listener: imDoneWithFail;
Background update tab;
background listener: imDoneWithFail; <- shouldn't happen, doesn't look like it conten't script even started to work as it didn't ask for permission. Looks like listener is fired up twice...
Background update tab;
content script: askForPermission(); <-sends message asking for permission to start
Bacground: go <- allows. 

在有人问我之前,我尝试使用长寿命连接,但我也有同样的问题。为什么会发生这种情况?

好的,我找到了一个答案,问题是函数改变了标签的url

function actNgo(url,arr){
    chrome.storage.local.set({
        array : arr,
        ndz : 1
    }, function () {
        chrome.tabs.update(
            tabId,
            {
                "url" : url,
                "active" : false
            }, function (tab) {
                console.log("tabId "+tabId);
            });
    });
}
函数,当给定与当前相同的url时,不会刷新选项卡,并且内容脚本不能作为新的启动。。。仍然不知道为什么侦听器会两次触发消息,但自从我的更改后,它就停止了

我不知道这个修复程序是否对任何人都有帮助,但我首先将选项卡url更改为空白,然后更改为新的

    chrome.tabs.update(
        tabId,
        {
            "url" : "about:blank",
            "active" : false
        }, function (tab) {
            console.log("bcgr: aktualizujStroneIObstaw: pusta: tabId "+tabId);
            chrome.tabs.update(
                tabId,
                {
                    "url" : url_beta,
                    "active" : false
                }, function (tab) {
                    console.log("bcgr: aktualizujStroneIObstaw: wlasciwa: tabId "+tabId);

                }
              );

可能您的内容脚本被注入到所有帧中。您可以编辑问题并添加manifest.json吗?顺便说一句,每次单击扩展工具栏图标时,您都会添加侦听器,尽管据推测,Chrome会忽略后续调用,因为回调是相同的。@wOxxOm我刚刚用清单更新了问题,我知道如果我启动脚本几次,会添加更多的侦听器,但我没有这样做,所以这是另外一回事。。。每个帧都能将自己的消息发送回后台吗?根据日志文件,内容脚本代码只触发一次。好吧,我在所有发送和接收内容脚本和后台脚本中消息的行上设置了断点。你能做到吗?或者将扩展上传到某个地方并链接到这里?