架构概览

扩展程序是网络平台中使用的 HTML、CSS、JavaScript、图片和其他文件的压缩包,用于自定义 Google Chrome 浏览体验。扩展程序是使用网络技术构建的,可以使用浏览器为开放网络提供的 API。

扩展程序具有多种功能,它们可以修改用户看到和与浏览器互动的 Web 内容,还可以扩展和更改浏览器本身的行为。

将扩展程序视为使 Chrome 浏览器成为最具个性化的浏览器的关键。

扩展程序文件

扩展程序的文件类型和目录数量各不相同,但它们都必须具有 [manifest][docs-manifest]。一些基本但实用的扩展程序可能只包含清单及其工具栏图标。

名为 manifest.json 的清单文件会向浏览器提供有关扩展程序的信息,例如最重要的文件以及扩展程序可能会使用的功能。

{
  "name": "My Extension",
  "version": "2.1",
  "description": "Gets information from Google.",
  "icons": {
    "128": "icon_16.png",
    "128": "icon_32.png",
    "128": "icon_48.png",
    "128": "icon_128.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["background_script.js"]
  },
  "permissions": ["https://*.google.com/", "activeTab"],
  "browser_action": {
    "default_icon": "icon_16.png",
    "default_popup": "popup.html"
  }
}

扩展程序必须有一个位于浏览器工具栏中的图标。用户可以通过工具栏图标轻松访问,让用户知道安装了哪些扩展程序。通过使用弹出式窗口的扩展程序,大多数用户通过点击该图标与该扩展程序互动。

Google Mail Checker 扩展程序使用浏览器操作

Google Mail Checker 扩展程序的屏幕截图

Mappy 扩展程序使用网页操作内容脚本

Mappy 扩展程序的屏幕截图

引用文件

与普通 HTML 网页中的文件一样,您可以使用相对网址引用扩展程序的文件。

<img src="images/my_image.png">

此外,每个文件也可以使用绝对网址访问。

chrome-extension://EXTENSION_ID/PATH_TO_FILE

在绝对网址中,EXTENSION_ID 是扩展程序系统为每个扩展程序生成的唯一标识符。转至网址 chrome://extensions 即可查看所有已加载扩展程序的 ID。PATH_TO_FILE 是该文件在扩展程序的顶层文件夹下的位置;它与相对网址匹配。

处理已解压的扩展程序时,扩展程序 ID 可能会发生变化。具体来说,如果从其他目录加载扩展程序,则已解压扩展程序的 ID 会发生变化;在打包扩展程序时,该 ID 会再次改变。如果扩展程序的代码依赖于绝对网址,它可以使用 chrome.runtime.getURL() 方法,以避免在开发过程中对 ID 进行硬编码。

架构

扩展程序的架构取决于其功能,但许多强大的扩展程序都会包含多个组件:

后台脚本

后台脚本是扩展程序的事件处理脚本;其中包含对扩展程序非常重要的浏览器事件的监听器。该事件会处于休眠状态,直到某个事件触发,然后执行指示的逻辑。有效的后台脚本仅在需要时才加载,在空闲时卸载。

界面元素

扩展程序的界面应该富有针对性且尽量精简。界面应自定义或增强浏览体验,而不会分散注意力。大多数扩展程序都有浏览器操作网页操作,但也可以包含其他形式的界面,例如上下文菜单、使用多功能框或创建键盘快捷键

扩展程序界面页面(例如 popup)可以包含具有 JavaScript 逻辑的普通 HTML 页面。扩展程序还可以调用 tabs.createwindow.open() 以显示扩展程序中存在的其他 HTML 文件。

使用页面操作和弹出式窗口的扩展程序可以使用声明式内容 API 在后台脚本中设置关于何时为用户提供弹出式窗口的规则。当满足条件时,后台脚本会与弹出式窗口通信,使图标可供用户点击。

一个浏览器窗口,其中包含显示弹出式窗口的页面操作

内容脚本

对网页执行读取或写入操作的扩展程序使用的是内容脚本。内容脚本包含在已加载到浏览器的页面上下文中执行的 JavaScript。内容脚本会读取和修改浏览器所访问网页的 DOM。

包含网页操作和内容脚本的浏览器窗口

内容脚本可以使用 storage API 交换消息并存储值来与其父级扩展程序进行通信。

显示内容脚本和父扩展程序之间的通信路径

选项页面

就像扩展程序允许用户自定义 Chrome 浏览器一样,您也可以在选项页面中自定义扩展程序。选项可用于启用功能,并允许用户选择与其需求相关的功能。

使用 Chrome API

除了可以访问与网页相同的 API 之外,扩展程序还可以使用扩展程序专用 API,这些 API 能够与浏览器紧密集成。扩展程序和网页都可以使用标准 window.open() 方法打开网址,但扩展程序可以使用 Chrome API tabs.create 方法指定应在哪个窗口中显示该网址。

异步方法与同步方法

大多数 Chrome API 方法都是异步的:它们会立即返回,无需等待操作完成。如果扩展程序需要知道异步操作的结果,可以向其传递一个回调函数。回调将在方法返回后(可能很晚)执行。

如果该扩展程序需要将用户当前选定的标签页导航到新网址,则需要获取当前标签页的 ID,然后将该标签页的地址更新为新网址。

如果 tabs.query 方法为同步方法,则抓取结果可能如下所示。

//THIS CODE DOESN'T WORK
var tab = chrome.tabs.query({'active': true}); //WRONG!!!
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();

此方法将失败,因为 query() 是异步的。它无需等待工作完成即可返回,且不会返回值。如果方法的签名中提供了回调参数,则该方法为异步方法。

// Signature for an asynchronous method
chrome.tabs.query(object queryInfo, function callback)

若要正确查询标签页并更新其网址,该扩展程序必须使用回调参数。

//THIS CODE WORKS
chrome.tabs.query({'active': true}, function(tabs) {
  chrome.tabs.update(tabs[0].id, {url: newUrl});
});
someOtherFunction();

在上述代码中,这些行按以下顺序执行:1、4、2。系统会先调用 query() 指定的回调函数,然后执行第 2 行,但仅在获得当前所选标签页的相关信息之后才执行。这会在 query() 返回后的某个时间发生。虽然 update() 是异步的,但代码不使用回调参数,因为扩展程序不会对更新结果执行任何操作。

// Synchronous methods have no callback option and returns a type of string
string chrome.runtime.getURL()

此方法会以 string 的形式同步返回网址,并且不执行其他异步工作。

更多详细信息

如需了解详情,请浏览 Chrome API 参考文档并观看以下视频。

页面之间的通信

扩展程序中的不同组件通常需要相互通信。不同的 HTML 网页可以使用 chrome.extension 方法(例如 getViews()getBackgroundPage())相互查找。当某个页面引用其他扩展页面后,第一个页面便可调用其他页面上的函数并操纵其 DOM。此外,扩展程序的所有组件都可以访问使用 storage API 存储的值,并通过消息传递进行通信。

节省数据流量和无痕模式

扩展程序可以使用 storage API、HTML5 Web Storage API,或通过发出可保存数据的服务器请求来保存数据。当扩展程序需要保存内容时,请先考虑该内容是否来自无痕式窗口。默认情况下,扩展程序不会在无痕式窗口中运行。

无痕模式承诺在该窗口中不会留下任何痕迹。在处理来自无痕式窗口的数据时,扩展程序应遵守此 promise。如果扩展程序通常会保存浏览记录,请勿在无痕式窗口中保存历史记录。不过,无论在无痕式窗口中,扩展程序都可以存储来自任何窗口的设置偏好设置。

如需检测窗口是否处于无痕模式,请检查相关 tabs.Tabwindows.Window 对象的 incognito 属性。

function saveTabData(tab) {
  if (tab.incognito) {
    return;
  } else {
    chrome.storage.local.set({data: tab.url});
  }
}

更进一步

阅读概览并完成使用入门教程后,开发者应该可以开始编写自己的扩展程序了!通过以下资源,更深入地了解自定义 Chrome。

  • 如需了解可用于调试扩展程序的选项,请参阅调试教程
  • Chrome 扩展程序可以访问强大的 API,远不止于开放 Web 提供的 API。 chrome.* API 文档将逐步介绍每个 API。
  • 扩展程序开发概览提供了数十个其他链接,指向与创建高级扩展程序相关的文档。