Chrome扩展程序消息传递重复邮件

时间:2013-12-12 18:08:16

标签: javascript google-chrome-extension

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

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

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

这是我的清单文件:

{
  "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>

这个来回传递消息的目标是:

  • 将脚本注入任何适当的页面
  • 脚本告诉后台它已被注入并准备接收订单。
  • 后台页面给出了订单。
  • 内容脚本根据这些订单执行某些操作。

1 个答案:

答案 0 :(得分:2)

如果我理解正确,问题是你一直在混淆packground-page和popup代码。

每次打开弹出窗口时都会执行弹出页面。这意味着每次弹出窗口时,都会注册几个新的侦听器(在弹出窗口关闭后继续存在)。因此,你最终会得到十几个相同的听众,对一个事件做出回应(反过来结果就是moe,最重要的是意外流量)。

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