如何从弹出窗口中与background.js进行交互?

时间:2012-03-02 17:09:50

标签: google-chrome-extension

有没有办法在popup.html(或popup.js)和后台脚本之间传递信息?

我希望弹出窗口显示来自用户帐户的信息或允许他们登录,但让background.js处理身份验证和其他逻辑。我在清单中声明了background.js,但似乎没有迹象表明它正在被使用。

编辑:如果我认为这一切都错了,并且有更好的方法可以做到这一点,那也会很棒。

3 个答案:

答案 0 :(得分:29)

请注意,后台页面和弹出窗口位于同一进程(扩展进程)中,因此一个页面可以获取另一个页面的DOM窗口,然后直接调用函数或设置变量。例如,弹出窗口可以调用chrome.extension.getBackgroundPage来修改背景:

chrome.extension.getBackgroundPage().variable = 42;

后台页面可以调用chrome.extension.getViews来获取弹出窗口:

var popups = chrome.extension.getViews({type: "popup"});
if (0 < popups.length)
  popups[0].variable = 42;

设置共享变量的另一种方法是使用传统的DOM API,因为每个扩展都有一个假的来源(例如&#34; eakjnniffhfegdpfehmnpcmjiameincp&#34;)。因此,当您在后台修改localStoragedocument.cookie或IndexedDB时,可以在弹出窗口中回读它。

也就是说,即使在扩展过程中的页面内,您仍可能希望使用传递API的消息,因为它可能会使您的代码更加统一。消息传递是与内容脚本通信的唯一方式。

答案 1 :(得分:9)

使用chrome.extension API

您可以来回发送请求,甚至可以更好地使用端口进行持续通信。

我给出的示例将在弹出窗口打开时连接的弹出窗口和后台页面之间创建双向通信。

只需创建一个socket.js文件,该文件包含在后台页面和弹出页面中。然后在每个上你可以声明:

new Socket();

这是socket.js的实现:

var Socket = function() {
    window.socket = this;

    this.port = chrome.extension.connect({name:"popupToBackground"});

    chrome.extension.onConnect.addListener(function(port) {
        if(port.name == "backgroundToPopup") {}
            else if(port.name == "popupToBackground") {
            window.socket.port = chrome.extension.connect({name:"backgroundToPopup"});
        }
        else {
            return;
        }

        port.onMessage.addListener(function(msg) {
            try {
                window[msg.namespace][msg.literal][msg.method].apply(this, msg.args);
            }
            catch(error) {
                // your failed action goes here.
            }
        });
    });
};

确保使消息侦听器中的泛型方法调用适合您。我喜欢上面给出的格式 - 它非常强大。要来回发送消息,只需将它们发布到套接字:

socket.post({ namespace: "myNamespace",
              literal: "myLiteral",
              method: "myMethod",
              args: ["argOne", "argTwo"]
           });
});

因此,如果这是从弹出页面执行的,那么后台页面将调用:

window.myNamespace.myLiteral.myMethod(argOne, argTwo);

对我来说,这是一个非常好的可重用的javascript对象。如果您愿意,您甚至可以添加特定的原型函数 - 这样更容易发送消息:

Socket.prototype = {
    sendOneTwo: function() {
        socket.post({ namespace: "myNamespace",
                      literal: "myLiteral",
                      method: "myMethod",
                      args: ["argOne", "argTwo"]
    });
};

现在你要说的是:

socket.sendOneTwo();

答案 2 :(得分:3)

出于调试目的,我发现这在弹出式JS中非常方便:

console = chrome.extension.getBackgroundPage().console