javascript - Chrome 扩展后台消息监听器启动两次

标签 javascript ajax google-chrome-extension listener

我有一个像这样工作的 chrome 扩展程序:

后台每隔几秒检查站点 x 是否发生更改,如果发生更改,后台会打开带有页面 Y 的新选项卡并执行一些页面自动化(在基于 ajax 的页面中填写调查)。页面自动化由内容脚本完成。内容脚本需要向后台请求许可才能开始工作。它通过发送消息并等待回复来实现。当内容脚本完成它的工作时,它会向后台发送消息,其中包含有关成功与否的信息。失败时应使用新链接更新选项卡,成功时应关闭选项卡。问题是,有时 - 并非总是如此,免费获取消息两次。 Once - when tab fails it's job, and second time just after tab is updated with new link.我希望我能知道为什么...

这是脚本:

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();
    }
});

标签更新看起来很简单:background.js

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);
            });
    });
}

内容脚本被注入(inject)网站,网站不会像基于 ajax 那样重新加载,即使 - 如果不满足适当的条件,消息也无法发送

内容.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. 

编辑: list

{
  "name": "Test script",
  "version": "0.0.78",
  "manifest_version": 2,
  "background": {
      "scripts": ["src/background/background.js"]
    },
  "icons": {
    "19": "icons/icon19.png"
  },
  "default_locale": "en",
  "options_ui": {
    "page": "src/options/index.html",
    "chrome_style": true
  },
  "browser_action": {
    "default_icon": "icons/icon19.png",
    "default_title": "Test",
    "default_popup": "src/browser_action/browser_action.html"
  },
  "permissions": [
    "http://localhost/survey/*",
    "storage",
    "contextMenus",
      "tabs",
      "webRequest"
  ],
    "content_scripts": [
    {
        "matches": [
        "http://localhost/survey/*",
        "https://localhost/survey/*"
      ],
      "js": [
        "js/jquery/jquery.min.js",
        "src/inject/content.js"
      ]
    }
  ]
}

在有人问之前 - 我尝试使用长期连接,但我遇到了同样的问题。为什么会这样?

最佳答案

好的,我找到了答案,问题在于功能更改选项卡的 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);

                }
              );

关于javascript - Chrome 扩展后台消息监听器启动两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33346070/

相关文章:

javascript - 无法通过ajax发送json数据

google-chrome - Chrome扩展警告 "Cannot load extension with file or directory name Thumbs.db. The filename is illegal."

c# - 如何用C#读取TD的值?

javascript - 在 setTimeout 回调后使用 "this"时,nodejs/js 很奇怪

javascript - Typescript - 具有静态成员的类与具有常量成员的命名空间的区别

javascript - 任何可能的方法来保存 html 中单击的元素并在 ajax 调用后检索

javascript - Jshint:循环中的匿名函数(问题)

javascript - JQuery 表单序列化

google-chrome - Chrome扩展程序自动触发

javascript - 如何检测 chrome 同步功能是否处于事件状态? - Chrome 扩展