javascript - Chrome 扩展消息传递重复消息

标签 javascript google-chrome-extension

我在传递消息时遇到了一些奇怪的结果。我有一个内容脚本与嵌入在我的弹出页面中的脚本进行交互。目前,他们反复向彼此发送相同的消息和回复。我觉得这与我的事件监听器触发过多有关,或者我为传递消息而编写的方法正在创建某种意外的消息循环。

我的弹出脚本有一些逻辑可以将我的内容脚本注入(inject)到用户访问的每个网页中:

document.addEventListener('DOMContentLoaded', function () {
    chrome.tabs.onUpdated.addListener(contextSwitch);

});

//after navigating to a new url
function contextSwitch() {
    var tabid = arguments[0];
    var changeinfo = arguments[1];
    var tab = arguments[2];
    //keeps the script from being injected into a tab that's still loading. 
    if(changeinfo.status === "complete"){
        chrome.tabs.executeScript(tabid, {file : "inject.js"}, postInject);
    }
    else if (changeinfo.status ==="loading"){
        console.log("loading fired");
    }
    else{
        console.log("Something went wrong.");
        console.log(changeinfo);
    }
}
//this fires after the script is injected. 
function postInject() {
    chrome.runtime.onConnect.addListener(function(port) {
        port.onMessage.addListener(messageBroker);
        port.postMessage({status:"connected"});
    });
}
//helps pick and choose what to do based on nthe message received
function messageBroker() {
var msg = arguments[0];
var sender = arguments[1];
  if(msg.status == "initialized"){
        sender.postMessage({status:"inject",contents:{notes:page.Notes}});  
  }
  }

内容脚本打开这样一个端口:

var extPort = chrome.runtime.connect({
    name : "CS:" + window.location.href
});

extPort.onMessage.addListener(function() {
    var msg = arguments[0];
    var sender = arguments[1];
    //the popup page sends the "connected" message after the port connects. 
    if (msg.status === "connected") {
        var initmsg = {
            status : "initialized",
            contents : {
                url : window.location.href
            }
        };
        sender.postMessage(initmsg);
    }

    if (msg.status === "inject") {
        var contents = msg.contents;
        if (contents) {
            for (item in contents) {
                //do stuff with the contents
            }

        }
    }
    sender.postMessage({
        status : "received"
    });
});

这是我的 list 文件:

{
  "name": "name",
  "version": "0.0.1",
  "description": "chrome extension",
  "permissions": [
    "activeTab",
    "tabs","<all_urls>","http://*/","https://*/"
  ],
  "browser_action": {
      "default_title": "ext",
      "default_icon": "icon.png",
      "default_popup": "popup.html"
  },
  "background": {
    "scripts": ["chrome.js"],
    "persistent": false
  },
  "manifest_version": 2,
  "content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'"
}

我的后台脚本像这样嵌入到我的弹出窗口中:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>popup</title>
        <meta name="description" content="">
        <meta name="author" content="alex">
        <script src="chrome.js"></script>
    </head>

    <body style="width:400px;height:400px;">
        <div id=menu> Menu </div>
        <a href="#" id="button1">button1</a>
        <a href="#" id="button2">button2</a>
    </body>
</html>

我来回传递消息的目标是:

  • 将脚本注入(inject)任何合适的页面
  • 脚本告诉后台它已经被注入(inject),可以接收订单了。
  • 后台页面给它命令。
  • 内容脚本根据这些命令执行一些操作。

最佳答案

如果我没理解错的话,问题是你混淆了 packground-page 和 popup 代码。

每次打开弹出窗口时都会执行弹出页面。这意味着每次显示弹出窗口时,都会注册几个新的监听器(在弹出窗口关闭后继续存在)。因此,您最终会得到十几个相同的监听器,响应一个事件(结果是 moe 和最重要的意外流量)。

我建议您看一下扩展的核心概念,以帮助理清思路:

关于javascript - Chrome 扩展消息传递重复消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20550946/

相关文章:

javascript - Chrome - 检测浏览器关闭或标签页关闭

javascript - 从 Gmail API 批量获取超过 10,000 封电子邮件的电子邮件发件人

javascript - 将 google maps api 合并到 chrome 扩展程序中/替代 document.write

javascript - 为什么我的 localStorage 复选框/ bool 值比较不适用于我的 Google Chrome 扩展程序?

javascript - chrome延长生命周期,后台任务

javascript - 获取函数内部异步函数的返回数据

javascript - 即使在 jQuery 中删除类名,也会触发 Click 事件

javascript - 每个 Promise 中的嵌套 Promise

javascript - 使用 Node Js 测量处理时间?

javascript - d3 饼 : redraw label on path change