Google Chrome扩展程序 - 架构问题

时间:2011-04-19 20:27:08

标签: architecture google-chrome communication

我一直在圈子里(可能是因为我有点新),以及如何在Chrome扩展程序中进行通信。

我正在尝试构建一个扩展程序:

1)有一个与用户交互的弹出窗口 2)根据用户在弹出窗口中选择的内容,修改当前选项卡的DOM 3)弹出窗口还需要能够从远程数据库服务器(即带有数据库的外部网站)发送和接收信息

对我而言,目前还不清楚如何构建所有部分之间的通信:我的数据库,弹出窗口,background.html,内容脚本,网页....

任何想法? 安东尼

2 个答案:

答案 0 :(得分:6)

我将尝试逐步解释我认为这样做的好方法。这并不意味着它是最好的方式,它只是一种推荐的方式:)


用户故事

如果我正确理解了这个问题,您想在网站上显示一个弹出窗口。根据用户在弹出窗口中选择的内容,将修改网站DOM。同样,您希望弹出窗口能够接收远程数据。

计划

根据上述要求,您将很快发现需要以下内容:

通过使用消息传递机制,您将能够在两个不同的世界(上下文菜单和背景页面)之间传递数据。每当您想要呼叫远程服务时,您都会通过Messaging请求。下面,我将解释整个过程中的每一步。


弹出

您的弹出窗口将只是您在JavaScript中动态创建的普通“div”元素。如下所示:

var overlayDOM= document.createElement('div');
... add your stuff to overlayDOM
document.body.appendChild(overlayDOM);

或者您可以使用iframe来保留样式。使用CSS技术,您可以将其设置为适当的样式,使其看起来像弹出窗口。你可以通过使用绝对定位或沿着这些线条的任何东西来做到这一点。

上下文菜单

现在有两种方法可以使用内容脚本。您需要问自己的问题如下:

  • 用户是否会从浏览器进程激活该弹出窗口?例如,弹出窗口是否会从任何扩展UI(上下文菜单,页面操作,浏览器操作,特定事件等)以编程方式显示。

  • 弹出窗口始终在DOM上可见,无需用户干预即可使其可见。

如果选择前者,则可以使用选项卡executeScript功能。这非常简单,您需要做的就是提供要注入D​​OM(网站)的代码或JavaScript文件。例如:

chrome.tabs.executeScript(tabId, {file: 'popup_overlay.js'});

如果您打算选择后者(弹出窗口始终显示在页面上)。您可以在manifest

中定义每个页面popup_overlay.js
"content_scripts": [
   {
     "matches": ["http://www.google.com/*"],
     "css": ["mystyles.css"],
     "js": ["popup_overlay.js"]
   }
],

背景页

后台页面将具有权限,以便它可以与远程数据库通信。您需要做的第一件事是通过manifest提供正确的权限。请务必查看Match Patterns以确保您的许可尽可能受限制。

"permissions": [
  "tabs",
  "http://www.mywebsite.com/"
],

设置权限后,您可以通过XmlHttpRequests(XHR)与远程服务进行通信。创建使用XHR的JavaScript服务API,随意使用您喜欢的任何设计。我个人喜欢使用JavaScript对象来组织我的代码。您的后台页面可以访问您创建的实例化服务API,并且可以在扩展的整个生命周期内使用。

// Lives in the Background Page
var service = new RemoteService();

消息传递

如上所述,Message Passing用于允许内容脚本和背景页面之间的通信。在您的情况下,您希望弹出窗口从后台页面获取一些数据(因为这是您的JS对象所在的位置)并返回结果。当您获得这些结果并将其显示在页面上时,因为您已经在与DOM相同的世界中。

您首先需要设置后台页面以接收请求,这是您设置请求侦听器的方式:

chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
  if (request.method == 'GetUserList')
    sendResponse({result: db.getGetUserList()});
  else if (request.method == 'GetUser')
    sendResponse({result: db.getGetUser(request.username)});
  else
    sendResponse({}); // snub them.
});

你可以使上面的爱好者,但为了解释,我正在关注Message Passing文件,它完美地解释了它。如上所示,我们正在为扩展请求创建一个监听器。您在侦听器中处理请求。正如您所注意到的,您也可以发送回复。在上面的例子中,我们正在发送我们请求的方法的适当结果。

在您的内容脚本中,您可以轻松地将请求发送到后台页面:

// Retrieve the username called mohamedmansour. Continuation from above.
chrome.extension.sendRequest({method: 'GetUser', username: 'mohamedmansour'}, function(response) {
  console.log(response.result);
});

在上面的代码片段中,我们从内容脚本向扩展发送请求以获取“mohamedmansour”的用户数据。然后将结果打印在控制台中。

一旦你开始思考Messaging,你就会发现将JSON消息发回第四个是多么容易。

希望有所帮助!

答案 1 :(得分:0)

以下是Chrome扩展架构的基于场景的描述。它以简单的方式描述了通信。

http://www.drdacademy.com/?id=the-architecture-of-a-chrome-extension