Skip to content

扩展与浏览器API

WebExtensions API是浏览器扩展的核心所在。它允许扩展深入到网页和浏览器中进行更改,检查并修改网络流量,以及控制原生浏览器用户界面的各个方面。

全局API命名空间

所有扩展都可以通过全局API命名空间进行访问。这可以通过chrome.*命名空间或browser.*命名空间来实现。

• Chromium浏览器和Safari浏览器倾向于使用chrome.*命名空间

• Firefox浏览器倾向于使用browser.*命名空间

所有浏览器都支持chrome.*命名空间,因此建议在所有扩展中都使用它。

Promises与Callbacks

WebExtensions API是在async/await成为行业标准之前编写的。最初的API实现使用callbacks来支持异步代码执行。例如,以下代码片段在收到消息响应后执行一个callback:

javascript
chrome.runtime.sendMessage("msg", (response) => { 
  console.log("Received a response!", response);
});

为了与现代编码规范保持一致,大多数浏览器已经对其API方法进行了改造,以同时支持callbacks和promises。上面的代码片段可以被重构为使用async/await:

javascript
const response = await chrome.runtime.sendMessage("msg"); 
console.log("Received a response!", response);

在进行这种更改时,需要了解以下几点:

• 并非所有API方法都已改编为支持promises。请查阅浏览器的文档,以确认是否支持。callbacks将始终有效。

• 对于每次方法调用,只能使用callback或promise,而不能同时使用两者。

• Mozilla的webextension-polyfill(https://github.com/mozilla/webextension-polyfill)可用于增强WebExtensions API方法,使其基于promises,而无需考虑托管浏览器的实现。

错误处理

WebExtensions API方法抛出的错误必须根据使用方式的不同进行不同的处理。如果你使用callbacks,当方法失败时,chrome.runtime.lastError属性将仅在callback处理器内部被定义:

javascript
chrome.tabs.executeScript(tabId, details, () => {
  if (chrome.runtime.lastError) {
    // 在此处处理错误
  }
});

如果你使用async/await,则可以使用.catch()或try/catch块来捕获错误:

javascript
chrome.tabs.executeScript(tabId, details).catch((e) => {
  // 在此处处理错误
});
// 或者
try {
  await chrome.tabs.executeScript(tabId, details);
} catch (e) {
  // 在此处处理错误
}

上下文受限的API

并非所有API都可以在任何地方使用:

• 一些API,如tabCapture和fileSystem,仅限于前台使用,意味着它们无法从后台服务工作者访问。

• Devtools API只能在devtools上下文中使用。

事件API

“事件API”指的是你可以如何向浏览器扩展中触发的事件添加事件监听器的一般模式。大多数WebExtensions API都使用这种格式。

格式

每种事件类型都有一个接口来添加、移除和检查监听器。例如,chrome.runtime.onMessage接口有以下方法:

  • chrome.runtime.onMessage.addListener()
  • chrome.runtime.onMessage.dispatch()
  • chrome.runtime.onMessage.hasListener()
  • chrome.runtime.onMessage.hasListeners()
  • chrome.runtime.onMessage.removeListener()

注意:dispatch()可用于强制分发事件,但未被记录,因此不应依赖它。

所有这些方法都被所有事件接口共享。addListener()用于将处理程序函数附加到事件触发时运行的函数,而hasListener()、hasListeners()和removeListener()用于查看和移除相同的函数。

以下示例使用其中一些方法来处理工具栏图标按钮点击事件:

示例 11-1a. manifest.json

json
{
  "name": "MVX",
  "version": "0.0.1",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js",
    "type": "module"
  },
  "action": {},
  "permissions": []
}

示例 11-1b. background.js

javascript
let count = 0;
function handler() {
  console.log("处理程序已执行!");
  if (++count > 4) {
    chrome.action.onClicked.removeListener(handler);
  }
}
// false
console.log(chrome.action.onClicked.hasListener(handler));
chrome.action.onClicked.addListener(handler); // true
console.log(chrome.action.onClicked.hasListener(handler));

此示例为onClicked事件设置了一个监听器,监听五个事件,然后注销自身。

事件过滤

如果你希望将事件处理器限制在特定域名上,你可能需要在处理器内部进行过滤。但是,更有效的方法是指示浏览器声明性地过滤匹配特定URL的事件。浏览器原生执行此过滤将带来显著的性能提升。

例如,下面的代码演示了如何在事件监听器中手动过滤URL:

javascript
chrome.webNavigation.onCommitted.addListener((event) => {
  if (!event.url.match(/^https:\/\/*.wikipedia\.org/)) {
    return; // 如果URL不匹配,则直接返回,不执行后续代码
  }
  // 处理过滤后的事件
});

然而,你可以通过向addListener方法传递一个过滤对象来让浏览器为你执行这个过滤:

javascript
chrome.webNavigation.onCommitted.addListener((event) => {
  // 处理过滤后的事件
}, { url: [{ hostSuffix: "wikipedia.org" }] }); // 只监听以"wikipedia.org"结尾的主机名的事件

WebExtensions API 快速参考

本节是扩展API的综合列表。每个API都包括一个演示常见用法的简短代码段和指向完整文档的链接。

提示:本书的配套扩展“Browser Extension Explorer”包含这些API的大多数交互式演示和源代码。你可以在这里获取它:Browser Extension Explorer

权限

chrome.permissions API允许你检查当前权限、添加或删除权限。你还可以添加在添加或删除权限时触发的事件处理器。

下面是一个使用chrome.permissions API请求“tabs”权限的示例:

javascript
chrome.action.onClicked.addListener(() => {
  // 只能在用户操作后才能请求权限
  const permissionsGranted = await chrome.permissions.request({ permissions: ['tabs'] });
  // 根据permissionsGranted的值判断权限是否被授予
});

// 检查是否拥有“tabs”权限
const hasPermissions = await chrome.permissions.contains({ permissions: ['tabs'] });
// 根据hasPermissions的值判断是否拥有权限

信息传递

一次性消息

chrome.runtime.sendMessage()方法可用于在扩展组件之间发送单条消息。它仅可用于从内容脚本发送消息。监听器可以在消息处理器内发送回复消息。

javascript
// 发送者
chrome.runtime.sendMessage(msg, (response) => {
  // 处理响应
});
// 接收者 
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  // 处理来自发送者的初始消息
  sendResponse(responseMsg);
});

要向特定的内容脚本发送一次性消息,必须使用chrome.tabs.sendMessage()并指定tabId:

javascript
// 发送者
chrome.tabs.sendMessage(tabId, msg, (response) => {
  // 处理响应
});
// 接收者(内容脚本)
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  // 处理来自发送者的初始消息
  sendResponse(responseMsg);
});

打开消息端口

可以打开持久消息端口来连接两个扩展组件,这些组件将来回发送大量消息。它仅可用于从内容脚本连接端口。

javascript
// 端点1
const port1 = chrome.runtime.connect({name: "portName"}); 
// 发出
port1.postMessage(msg);
// 接收
port1.onMessage.addListener((msg) => {});
// 端点2
let port2 = null; 
chrome.runtime.onConnect.addListener((p) => {
port2 = p; });
// 发出
port2.postMessage(msg);
// 接收
port2.onMessage.addListener((msg) => {});

要将端口连接到特定的内容脚本,必须使用chrome.tabs.connect()并指定tabId:

javascript
// 端点1
const port1 = chrome.tabs.connect(tabId, {name: "portName"}); 
// 发出
port1.postMessage(msg);
// 接收
port1.onMessage.addListener((msg) => {});
// 端点2(内容脚本)
let port2 = null; 
chrome.runtime.onConnect.addListener((p) => {
  port2 = p; 
});
// 发出
port2.postMessage(msg);
// 接收
port2.onMessage.addListener((msg) => {});

与原生应用程序通信

扩展可以与原生应用程序交换消息。如果已知原生应用程序的名称(例如,com.my_company.my_application),则扩展可以像针对内容脚本一样针对它:

javascript
chrome.runtime.sendNativeMessage(applicationName, msg, (response) => {});
chrome.tabs.connectNative(applicationName, {name: "portName"});

在“跨浏览器扩展”章节中展示了此类通信的一个示例。Safari扩展使用原生消息传递将扩展连接到原生的iOS或macOS应用程序。

与其他扩展通信

要向另一个扩展发送一次性消息,可以将扩展的ID传递给chrome.runtime.sendMessage():

javascript
// 发送者
chrome.runtime.sendMessage(extensionId, msg, (response) => {
  // 处理响应
});
// 接收者(外部扩展)
chrome.runtime.onMessageExternal.addListener((msg, sender, sendResponse) => {
  // 处理来自发送者的初始消息
  sendResponse(responseMsg);
});

要将端口连接到另一个扩展,可以使用chrome.runtime.connect()并指定extensionId:

javascript
// 扩展1
const port1 = chrome.runtime.connect(extensionId, {name: "portName"});
// 发出
port1.postMessage(msg);
// 接收
port1.onMessage.addListener((msg) => {});
// 扩展2
let port2 = null; 
chrome.runtime.onConnectExternal.addListener((p) => {
  port2 = p; 
});
// 发出
port2.postMessage(msg);
// 接收
port2.onMessage.addListener((msg) => {});

此方法还允许常规网页(而非内容脚本)以完全相同的方式向您的扩展发送消息。该API在网页的JavaScript运行时中公开,如果满足以下条件,您的扩展可以接收消息:

  • 宿主页面知道您的扩展的ID,并将其传递给runtime.connect()或runtime.sendMessage()
  • 您的扩展在清单的externally_connectable字段下将网页URL列入白名单

存储

扩展存储API是一个简单但功能强大的键值存储。您可以使用以下四种主要的存储选项:

  • storage.local:仅在本地浏览器上存储值
  • storage.sync:在已验证的浏览器会话之间共享存储的值
  • storage.session:在内存中存储值,浏览器关闭时将丢弃这些值
  • storage.managed:一个只读存储,专为企业用户使用

local、sync和session具有以下共同点:

  • 仅具有存储权限时,每个存储的默认最大大小为5MB。使用额外的unlimitedStorage权限可以移除此限制。
  • 每个存储都仅具有get()和set()方法。这些方法是异步的,并且都可以并行读写。
  • 可以通过设置onChanged处理程序来监听每个存储的更改。
  • 可以原样存储和检索纯JavaScript对象,无需进行序列化/反序列化。

以下示例展示了并行化的get/set操作以及onChanged处理程序:

javascript
// 监听存储更改并打印到控制台
chrome.storage.onChanged.addListener(console.log);

// 设置存储项foo的值为"tmp"
await chrome.storage.local.set({ foo: "tmp" });
// 控制台输出: { foo: { newValue: "tmp" } }

// 更新存储项foo的值为"bar",并添加新的存储项baz,值为"qux"
await chrome.storage.local.set({ foo: "bar", baz: "qux" });
// 控制台输出: 
// {
//   foo: { oldValue: "tmp", newValue: "bar" },
//   baz: { newValue: "qux" }
// }

// 从存储中获取foo和baz的值
console.log(await chrome.storage.local.get(["foo", "baz"]));
// 控制台输出: { foo: "bar", baz: "qux" }

身份验证

chrome.identity API用于管理身份验证状态和OAuth流程。Google Chrome支持额外的方法,允许在浏览器内进行原生身份验证。所有浏览器都支持使用launchWebAuthFlow进行通用的OAuth流程。

javascript
// 使用原生浏览器OAuth进行身份验证
chrome.identity.getAuthToken(
  { interactive: true },
  (token) => {
    if (token) {
      // 获取到令牌后,可以进一步获取用户信息
      const info = await chrome.identity.getProfileUserInfo({ accountStatus: "ANY" });
      // 处理用户信息
    }
  }
);

// 支持通用的OAuth流程
chrome.identity.launchWebAuthFlow(
  {
    url: authUrl, // OAuth认证URL
    interactive: true,
  },
  (redirectUrl) => {
    if (redirectUrl) {
      // 处理重定向URL,提取认证结果
    }
  }
);

注意:此API在“网络”章节中有深入介绍。

网络请求

网络请求API包括declarativeNetRequest、webRequest和webNavigation:

  • declarativeNetRequest用于指示浏览器根据扩展定义的一组规则来管理页面流量。
  • webRequest用于通过JavaScript处理程序来控制页面流量。
  • webNavigation用于检查标签级导航事件。
javascript
// 使用DNR阻止访问wikipedia.org

chrome.declarativeNetRequest.updateDynamicRules({
  addRules: [{
    id: 1,
    priority: 1,
    action: {
      type: "block"
    },
    condition: {
      urlFilter: "https://www.wikpedia.org",
    },
  }]
});
javascript
// 使用webRequest阻止访问wikipedia.org
chrome.webRequest.onBeforeRequest.addListener(
  (details) => {
    return {
      cancel: true
    };
  },
  { urls: ["*://www.wikipedia.org/*"] },
  ["blocking"]
);
javascript
// 使用webNavigation记录所有标签流量
chrome.webNavigation.onCompleted.addListener((details) => {
  console.log(details.url);
});

注意:这些API在“网络”一章中有详细介绍。

国际化

chrome.i18n API 允许您确定系统语言,并从您的 _locales/_code_/messages.json 文件中读取消息。以下示例读取活动系统语言并从该语言中检索消息:

javascript
chrome.i18n.getUILanguage(); 
chrome.i18n.getMessage("foo_message");

浏览器和系统控制

WebExtensions API 提供了多种方法来检查和控制宿主系统或用户界面。

电源

• power API – Chrome 开发者:https://developer.chrome.com/docs/extensions/reference/power/

chrome.power API 允许扩展程序防止宿主系统进入睡眠状态。

javascript
// 保持系统活跃,
// 但允许屏幕变暗或关闭。
chrome.power.requestKeepAwake("system");

// 保持屏幕和系统活跃
chrome.power.requestKeepAwake("display");

// 允许宿主正常行为
chrome.power.releaseKeepAwake();

Omnibox

chrome.omnibox API 允许您将特殊的搜索界面嵌入到浏览器的 URL 栏中(图 11-1)。您可以控制触发界面的关键字、显示哪些结果、如何呈现结果,以及选择结果后会发生什么。 11-1

以下示例在地址栏中填充了一个建议列表,该列表通过文本匹配进行过滤。如果选择了其中一个建议,则会导航到该 URL。

javascript
const suggestions = [
  {
    content: url1,
    description: `
      ${title1}
      <dim>${subtitle1}</dim>
      <url>${url1}</url>`,
  }, {
    content: url2,
    description: `
      ${title2}
      <dim>${subtitle2}</dim>
      <url>${url2}</url>`,
  }
];

chrome.omnibox.onInputChanged.addListener((text, suggest) => {
  suggest(suggestions.filter(s => s.content.includes(text)));
});

chrome.omnibox.onInputEntered.addListener((text, disposition) => {
  // 导航到选中的 URL
  chrome.tabs.update(activeTabId, { url: text });
});

动作(Action)

chrome.action API 允许您控制扩展工具栏图标,包括外观、标题文本、徽章内容、徽章颜色、弹出页面和点击处理程序(图 11-2)。

11-2

javascript
chrome.action.onClicked.addListener(() => {});
chrome.action.setTitle({ title: "foo" });
chrome.action.setBadgeText({ text: "bar" }); // 注意这里应该是 `text` 而不是 `title`
chrome.action.setPopup({
 popup: chrome.runtime.getURL("new_popup.html")
});

通知(Notifications)

chrome.notification API 允许扩展使用宿主操作系统的通知机制向用户显示丰富的通知(图 11-3)。

11-3

javascript
chrome.notifications.create("NOTIFICATION_ID", {
   type: "basic",
   iconUrl: "/img.png",
   title: "My notification!",
   message: "This is the message",
   priority: 2
});

上下文菜单(Context Menu)

chrome.contextMenus API 允许扩展在整个浏览器的右键菜单和上下文菜单中添加交互选项(图 11-4)。

11-4

javascript
chrome.contextMenus.create({
 id: "demo-radio",
 title: "Select a radio button...",
 contexts: ["all"],
});

for (let i of [1, 2, 3, 4, 5]) {
 chrome.contextMenus.create({
   id: `demo-radio-${i}`,
   parentId: "demo-radio",
   title: `Radio ${i}`,
   contexts: ["all"],
   type: "radio",
 });
}

chrome.contextMenus.create({
 id: "demo-media",
 title: "You right clicked a media element",
 contexts: ["image", "video", "audio"],
});

chrome.contextMenus.onClicked.addListener((info, tab) => {});

页面和屏幕截图(Page and Screen Capture)

扩展能够以多种方式捕获系统的当前状态:保存HTML、拍摄活动标签的图像或从当前桌面捕获媒体。

javascript
// 将特定标签保存为MHTML
chrome.pageCapture.saveAsMHTML({
  tabId: 123
});

// 捕获当前活动标签的可见区域。
chrome.action.onClicked.addListener(() => {
  chrome.tabCapture.capture({ video: true }, (stream) => {});
});

// 捕获屏幕、单个窗口或标签的内容。
chrome.desktopCapture.chooseDesktopMedia({
  sources: ["screen"],
}, (streamId, options) => {});

// 捕获指定窗口中当前活动标签的可见区域。
chrome.tabs.captureVisibleTab((dataUrl) => {});

代理(Proxy)

使用chrome.proxy API管理浏览器的代理设置。

MDN注释:Google Chrome提供了一个扩展API,也称为“proxy”,其功能与此API类似,扩展可以使用它来实现代理策略。然而,Chrome API的设计与这个API完全不同。由于此API与Chrome代理API不兼容,因此此API仅通过浏览器命名空间提供。

javascript
chrome.proxy.settings.set({
  value: {
    mode: "fixed_servers",
    rules: {
      proxyForHttp: {
        scheme: "socks5",
        host: "192.168.1.2",
      },
      bypassList: ["wikipedia.org"],
    },
  },
  scope: "regular",
}, () => {});

浏览器状态管理(Browser State Management)

WebExtensions API为您提供了一套广泛的工具来管理用户浏览器的状态。

字体设置(Font Settings)

该API允许扩展管理某些字体设置,以依赖于特定的通用字体族和语言脚本。

javascript
chrome.fontSettings.getFont({
  genericFamily: 'standard',
  script: 'Egyp'
}, (details) => {});

chrome.fontSettings.setFont({
  genericFamily: 'serif',
  script: 'Jpan',
  fontId: 'Comic Sans'
});

内容设置(Content Settings)

此API允许您按站点而不是全局自定义浏览器的行为:启用或禁用Cookie、JavaScript和插件。以下每个属性都有get()、set()和clear()方法:

  • automaticDownloads(自动下载)
  • camera(摄像头)
  • cookies(Cookie)
  • fullscreen(全屏)
  • images(图像)
  • javascript(JavaScript)
  • location(位置)
  • microphone(麦克风)
  • mouselock(鼠标锁定)
  • notifications(通知)
  • plugins(插件)
  • popups(弹出窗口)
  • unsandboxedPlugins(非沙盒插件)

chrome.cookies API是浏览器Cookie的创建/读取/更新/销毁接口。

javascript
const cookies = await chrome.cookies.getAll();
chrome.cookies.set({
  "name": "foo",
  "url": "https://www.wikipedia.org",
  "value": "bar"
});
chrome.cookies.remove({
  "name": "foo",
  "url": "https://www.wikipedia.org"
});
chrome.cookies.onChanged.addListener(() => {});

书签(Bookmarks)

chrome.bookmarks API是浏览器书签的创建/读取/更新/销毁接口。它包括管理书签层次结构的方法。

javascript
chrome.bookmarks.create({
  'title': 'Wikipedia',
  'url': 'https://www.wikipedia.org'
});
const allBookmarks = await chrome.bookmarks.getTree();
const matchingNodes = await chrome.bookmarks.search({ query: 'wikipedia' });

历史记录(History)

• history API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/history/

• history API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/history

chrome.history API是浏览器浏览历史的创建/读取/更新/销毁接口。

javascript
chrome.history.deleteAll();
const allPages = await chrome.history.search();
// 最近30分钟内的Wikipedia页面
const pages = await chrome.history.search({
  text: 'wikipedia',
  startTime: Date.now() - (30 * 60 * 1E3)
});

下载(Downloads)

chrome.downloads API是浏览器下载的创建/读取/更新/销毁接口。“创建”下载意味着强制浏览器从指定URL下载。

javascript
// 开始下载
chrome.downloads.download({
  url: "https://www.wikipedia.org/portal/wikipedia.org/assets/img/Wikipedia-logo-v2@2x.png",
});
const allDownloads = await chrome.downloads.search({});

常用网站(Top Sites)

此API允许扩展读取显示在新标签页上的“常用网站”(访问最多的网站)。

javascript
const topSites = await chrome.topSites.get();

Browsing Data(浏览数据)

此API允许扩展程序以编程方式删除浏览数据,涵盖多个类别。

javascript
chrome.browsingData.remove({
// 过去24小时
"since": (Date.now() - 24 * 60 * 60 * 1E3)
}, {
  "appcache": true,
  "cache": true,
  "cacheStorage": true,
  "cookies": true,
  "downloads": true,
  "fileSystems": true,
  "formData": true,
  "history": true,
  "indexedDB": true,
  "localStorage": true,
  "passwords": true,
  "serviceWorkers": true,
  "webSQL": true
});

Sessions(会话)

此API允许扩展程序以编程方式查看并重新打开最近关闭的标签页。

javascript
const recentlyClosed =
await chrome.sessions.getRecentlyClosed();
// 恢复最近关闭的标签页
chrome.sessions.restore();

Tabs and Windows(标签页和窗口)

这些API允许浏览器完全控制出现在浏览器内部的标签页和窗口。它可以执行创建、删除、检查、修改、重新排列、固定和静音等任务。

javascript
// 获取当前活动标签页
const [activeTab] = await chrome.tabs.query({ active: true, currentWindow: true });

// 创建一个新标签页
chrome.tabs.create({
  active: false,
  url: "https://www.wikipedia.org",
});

// 关闭一个标签页
chrome.tabs.remove(tabId);

// 重新加载一个标签页
chrome.tabs.reload(tabId);

// 创建一个新窗口
chrome.windows.create({
  focused: true,
  url: "https://www.wikipedia.org",
});

// 关闭一个窗口
chrome.windows.remove(windowId);

// 获取所有标签组
const allTabGroups = await chrome.tabGroups.query();

// 更新一个标签组
chrome.tabGroups.update(groupId, { title: "foo" });

调试器

chrome.debugger API允许您以编程方式控制浏览器的调试器。使用它,您可以执行Devtools API能够执行的几乎所有操作,包括查询响应体(前提是浏览器的开发者工具界面未打开)。

javascript
chrome.debugger.attach(tabId, "1.0", () => {});
chrome.debugger.sendCommand(tabId, "Debugger.enable");
chrome.debugger.sendCommand(tabId, "Debugger.setBreakpointByUrl", {
  lineNumber: 10,
  url: 'https://www.wikipedia.org/script.js'
});

搜索

此API允许您以编程方式在浏览器的默认搜索引擎中执行搜索。

javascript
chrome.search.query({
  disposition: "NEW_TAB",
  text: "wikipedia"
});

闹钟

此API用于安排在未来运行的代码。它在概念上类似于setTimeout()和setInterval(),但它能够唤醒服务工作者。

javascript
// 1分钟后触发闹钟事件
chrome.alarms.create({ delayInMinutes: 1 });

// 每5分钟触发一次闹钟事件
chrome.alarms.create({ periodInMinutes: 5 });

// 90秒后触发闹钟事件
chrome.alarms.create({ when: (Date.now() + 90 * 1E3) });

chrome.alarms.onAlarm.addListener((alarm) => {});

脚本

此API用于以编程方式将JavaScript或CSS注入页面。

javascript
function fooScript() {}

// 注入一个函数
chrome.scripting.executeScript({
  target: { tabId: 123 },
  function: fooScript
});

// 注入一个脚本文件
chrome.scripting.executeScript({
  target: { tabId: 123 },
  files: ['script.js']
});

// 注入CSS字符串
chrome.scripting.insertCSS({
  target: { tabId: 123 },
  css: 'body { background-color: red; }'
});

// 注入CSS文件
chrome.scripting.insertCSS({
  target: { tabId: 123 },
  files: ['styles.css']
});

DOM

文本转语音

tts API 允许你指示浏览器使用其原生文本转语音引擎大声朗读文本。

javascript
// 浏览器将大声朗读文本
chrome.tts.speak('Foo', {'lang': 'en-US', 'rate': 2.0});
// 等待之前的语音播放完成
chrome.tts.speak('Bar', {'enqueue': true});
// 立即停止语音
chrome.tts.stop();

隐私

此 API 允许扩展程序获取和设置用户的隐私控制。

javascript
chrome.privacy.services.searchSuggestEnabled.get({}, (details) => {
  if (details.levelOfControl === 'controllable_by_this_extension') {
    chrome.privacy.services.searchSuggestEnabled.set({ value: true });
  }
});

空闲

此 API 指示主机系统何时处于空闲状态。

javascript
// 每30秒检查一次系统状态
chrome.idle.queryState(30);
chrome.idle.onStateChanged.addListener(() => {});

开发者工具

javascript
// 创建开发者工具面板
chrome.devtools.panels.create("Panel title", "path/to/icon.png", "panel.html");
// 嗅探活动页面的流量
chrome.devtools.network.onNavigated.addListener((url) => {});

注意: 此主题在 Devtools Pages 章节中有所涵盖。

扩展程序内省

javascript
const popupUrl = chrome.extension.getURL("popup.html");
const allViews = chrome.extension.getViews();
const popups = chrome.extension.getViews({ type: "popup" });

扩展程序管理

javascript
const selfInfo = chrome.management.getSelf();
// 卸载运行中的扩展程序
chrome.management.uninstallSelf();
const manifest = chrome.runtime.getManifest();
// 重新加载扩展程序
chrome.runtime.reload();
// 指定卸载后将用户引导到的 URL
chrome.runtime.setUninstallURL("https://www.wikipedia.org");

系统状态

仅企业版可用 以下 API 仅可由企业策略强制安装的扩展程序使用,本章未涵盖:

  • enterprise.deviceAttributes
  • enterprise.hardwarePlatform
  • enterprise.networkingAttributes
  • enterprise.platformKeys

仅 Firefox 可用 以下 API 仅可在 Firefox 上使用,本章未涵盖:

  • captivePortal
  • contextualIdentites
  • dns
  • find
  • menus
  • pcks11
  • sidebarAction
  • theme
  • userScripts

仅 Chrome OS 可用 以下 API 仅可在 ChromeOS 上使用,本章未涵盖:

  • accesibilityFeatures
  • audio
  • certificateProvider
  • fileBrowserHandler
  • fileSystemProvider
  • input.ime
  • loginState
  • platformKeys
  • printing
  • printingMetrics
  • restart
  • restartAfterDelay
  • vpnProvider

已弃用

以下 API 已弃用,不应使用:

  • instanceID
  • gcm

总结

在本章中,我们涵盖了 WebExtensions API 的各种特性,包括 promise 和回调、错误处理以及事件 API。最后,我们逐一介绍了每个 API,了解了它们的用途,并查看了每个 API 的代码片段。 在下一章中,我们将讨论启用这些 API 所需的权限,以及管理扩展程序权限的最佳方式。