扩展与浏览器API
WebExtensions API是浏览器扩展的核心所在。它允许扩展深入到网页和浏览器中进行更改,检查并修改网络流量,以及控制原生浏览器用户界面的各个方面。
全局API命名空间
所有扩展都可以通过全局API命名空间进行访问。这可以通过chrome.*命名空间或browser.*命名空间来实现。
• Chromium浏览器和Safari浏览器倾向于使用chrome.*命名空间
• Firefox浏览器倾向于使用browser.*命名空间
所有浏览器都支持chrome.*命名空间,因此建议在所有扩展中都使用它。
Promises与Callbacks
WebExtensions API是在async/await成为行业标准之前编写的。最初的API实现使用callbacks来支持异步代码执行。例如,以下代码片段在收到消息响应后执行一个callback:
chrome.runtime.sendMessage("msg", (response) => {
console.log("Received a response!", response);
});
为了与现代编码规范保持一致,大多数浏览器已经对其API方法进行了改造,以同时支持callbacks和promises。上面的代码片段可以被重构为使用async/await:
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处理器内部被定义:
chrome.tabs.executeScript(tabId, details, () => {
if (chrome.runtime.lastError) {
// 在此处处理错误
}
});
如果你使用async/await,则可以使用.catch()或try/catch块来捕获错误:
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
{
"name": "MVX",
"version": "0.0.1",
"manifest_version": 3,
"background": {
"service_worker": "background.js",
"type": "module"
},
"action": {},
"permissions": []
}
示例 11-1b. background.js
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:
chrome.webNavigation.onCommitted.addListener((event) => {
if (!event.url.match(/^https:\/\/*.wikipedia\.org/)) {
return; // 如果URL不匹配,则直接返回,不执行后续代码
}
// 处理过滤后的事件
});
然而,你可以通过向addListener
方法传递一个过滤对象来让浏览器为你执行这个过滤:
chrome.webNavigation.onCommitted.addListener((event) => {
// 处理过滤后的事件
}, { url: [{ hostSuffix: "wikipedia.org" }] }); // 只监听以"wikipedia.org"结尾的主机名的事件
WebExtensions API 快速参考
本节是扩展API的综合列表。每个API都包括一个演示常见用法的简短代码段和指向完整文档的链接。
提示:本书的配套扩展“Browser Extension Explorer”包含这些API的大多数交互式演示和源代码。你可以在这里获取它:Browser Extension Explorer
权限
- Permissions API – Chrome 开发者文档:Chrome Permissions API 文档
- Permissions API – MDN:MDN Permissions API 文档
chrome.permissions
API允许你检查当前权限、添加或删除权限。你还可以添加在添加或删除权限时触发的事件处理器。
下面是一个使用chrome.permissions
API请求“tabs”权限的示例:
chrome.action.onClicked.addListener(() => {
// 只能在用户操作后才能请求权限
const permissionsGranted = await chrome.permissions.request({ permissions: ['tabs'] });
// 根据permissionsGranted的值判断权限是否被授予
});
// 检查是否拥有“tabs”权限
const hasPermissions = await chrome.permissions.contains({ permissions: ['tabs'] });
// 根据hasPermissions的值判断是否拥有权限
信息传递
- Chrome 信息传递概览 – Chrome 开发者: https://developer.chrome.com/docs/extensions/mv3/messaging/
- runtime API – Chrome 开发者:https://developer.chrome.com/docs/extensions/reference/runtime/
- runtime API – MDN:https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/
- tabs API – Chrome 开发者:https://developer.chrome.com/docs/extensions/reference/tabs/
- tabs API – MDN:https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/ 扩展信息传递API用于在扩展的不同部分之间或扩展与外部实体(如另一个扩展、活动网页或外部程序)之间发送消息。
一次性消息
chrome.runtime.sendMessage()方法可用于在扩展组件之间发送单条消息。它仅可用于从内容脚本发送消息。监听器可以在消息处理器内发送回复消息。
// 发送者
chrome.runtime.sendMessage(msg, (response) => {
// 处理响应
});
// 接收者
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
// 处理来自发送者的初始消息
sendResponse(responseMsg);
});
要向特定的内容脚本发送一次性消息,必须使用chrome.tabs.sendMessage()并指定tabId:
// 发送者
chrome.tabs.sendMessage(tabId, msg, (response) => {
// 处理响应
});
// 接收者(内容脚本)
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
// 处理来自发送者的初始消息
sendResponse(responseMsg);
});
打开消息端口
可以打开持久消息端口来连接两个扩展组件,这些组件将来回发送大量消息。它仅可用于从内容脚本连接端口。
// 端点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:
// 端点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),则扩展可以像针对内容脚本一样针对它:
chrome.runtime.sendNativeMessage(applicationName, msg, (response) => {});
chrome.tabs.connectNative(applicationName, {name: "portName"});
在“跨浏览器扩展”章节中展示了此类通信的一个示例。Safari扩展使用原生消息传递将扩展连接到原生的iOS或macOS应用程序。
与其他扩展通信
要向另一个扩展发送一次性消息,可以将扩展的ID传递给chrome.runtime.sendMessage():
// 发送者
chrome.runtime.sendMessage(extensionId, msg, (response) => {
// 处理响应
});
// 接收者(外部扩展)
chrome.runtime.onMessageExternal.addListener((msg, sender, sendResponse) => {
// 处理来自发送者的初始消息
sendResponse(responseMsg);
});
要将端口连接到另一个扩展,可以使用chrome.runtime.connect()并指定extensionId:
// 扩展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 – Chrome开发者文档:https://developer.chrome.com/docs/extensions/reference/storage/
- 存储API – MDN:https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage
扩展存储API是一个简单但功能强大的键值存储。您可以使用以下四种主要的存储选项:
- storage.local:仅在本地浏览器上存储值
- storage.sync:在已验证的浏览器会话之间共享存储的值
- storage.session:在内存中存储值,浏览器关闭时将丢弃这些值
- storage.managed:一个只读存储,专为企业用户使用
local、sync和session具有以下共同点:
- 仅具有存储权限时,每个存储的默认最大大小为5MB。使用额外的unlimitedStorage权限可以移除此限制。
- 每个存储都仅具有get()和set()方法。这些方法是异步的,并且都可以并行读写。
- 可以通过设置onChanged处理程序来监听每个存储的更改。
- 可以原样存储和检索纯JavaScript对象,无需进行序列化/反序列化。
以下示例展示了并行化的get/set操作以及onChanged处理程序:
// 监听存储更改并打印到控制台
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" }
身份验证
- identity API – Chrome开发者文档:https://developer.chrome.com/docs/extensions/reference/identity/
- identity API – MDN:https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/identity
chrome.identity API用于管理身份验证状态和OAuth流程。Google Chrome支持额外的方法,允许在浏览器内进行原生身份验证。所有浏览器都支持使用launchWebAuthFlow进行通用的OAuth流程。
// 使用原生浏览器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在“网络”章节中有深入介绍。
网络请求
- declarativeNetRequest API – Chrome 开发者: https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/
- webRequest API – Chrome 开发者: https://developer.chrome.com/docs/extensions/reference/webRequest/
- webRequest API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest
- webNavigation API – Chrome 开发者: https://developer.chrome.com/docs/extensions/reference/webNavigation/
- webNavigation API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation
网络请求API包括declarativeNetRequest、webRequest和webNavigation:
- declarativeNetRequest用于指示浏览器根据扩展定义的一组规则来管理页面流量。
- webRequest用于通过JavaScript处理程序来控制页面流量。
- webNavigation用于检查标签级导航事件。
// 使用DNR阻止访问wikipedia.org
chrome.declarativeNetRequest.updateDynamicRules({
addRules: [{
id: 1,
priority: 1,
action: {
type: "block"
},
condition: {
urlFilter: "https://www.wikpedia.org",
},
}]
});
// 使用webRequest阻止访问wikipedia.org
chrome.webRequest.onBeforeRequest.addListener(
(details) => {
return {
cancel: true
};
},
{ urls: ["*://www.wikipedia.org/*"] },
["blocking"]
);
// 使用webNavigation记录所有标签流量
chrome.webNavigation.onCompleted.addListener((details) => {
console.log(details.url);
});
注意:这些API在“网络”一章中有详细介绍。
国际化
- i18n API – Chrome 开发者:https://developer.chrome.com/docs/extensions/reference/i18n/
- i18n API – MDN:https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/i18n
chrome.i18n API 允许您确定系统语言,并从您的 _locales/_code_/messages.json
文件中读取消息。以下示例读取活动系统语言并从该语言中检索消息:
chrome.i18n.getUILanguage();
chrome.i18n.getMessage("foo_message");
浏览器和系统控制
WebExtensions API 提供了多种方法来检查和控制宿主系统或用户界面。
电源
• power API – Chrome 开发者:https://developer.chrome.com/docs/extensions/reference/power/
chrome.power API 允许扩展程序防止宿主系统进入睡眠状态。
// 保持系统活跃,
// 但允许屏幕变暗或关闭。
chrome.power.requestKeepAwake("system");
// 保持屏幕和系统活跃
chrome.power.requestKeepAwake("display");
// 允许宿主正常行为
chrome.power.releaseKeepAwake();
Omnibox
- omnibox API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/omnibox/
- omnibox API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/omnibox
chrome.omnibox API 允许您将特殊的搜索界面嵌入到浏览器的 URL 栏中(图 11-1)。您可以控制触发界面的关键字、显示哪些结果、如何呈现结果,以及选择结果后会发生什么。
以下示例在地址栏中填充了一个建议列表,该列表通过文本匹配进行过滤。如果选择了其中一个建议,则会导航到该 URL。
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)
- action API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/action/
- action API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/action
chrome.action API 允许您控制扩展工具栏图标,包括外观、标题文本、徽章内容、徽章颜色、弹出页面和点击处理程序(图 11-2)。
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)
- notifications API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/notifications/
- notifications API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/notifications
chrome.notification API 允许扩展使用宿主操作系统的通知机制向用户显示丰富的通知(图 11-3)。
chrome.notifications.create("NOTIFICATION_ID", {
type: "basic",
iconUrl: "/img.png",
title: "My notification!",
message: "This is the message",
priority: 2
});
上下文菜单(Context Menu)
- contextMenus API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/contextMenus/
- menus API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/menus
chrome.contextMenus API 允许扩展在整个浏览器的右键菜单和上下文菜单中添加交互选项(图 11-4)。
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)
- pageCapture API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/pageCapture/
- tabCapture API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/tabCapture/
- tabCapture API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/captureTab
- desktopCapture API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/desktopCapture/
- captureVisibleTab API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/tabs/#method-captureVisibleTab
- captureVisibleTab API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/captureVisibleTab
扩展能够以多种方式捕获系统的当前状态:保存HTML、拍摄活动标签的图像或从当前桌面捕获媒体。
// 将特定标签保存为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)
- proxy API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/proxy/
- proxy API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/proxy
使用chrome.proxy API管理浏览器的代理设置。
MDN注释:Google Chrome提供了一个扩展API,也称为“proxy”,其功能与此API类似,扩展可以使用它来实现代理策略。然而,Chrome API的设计与这个API完全不同。由于此API与Chrome代理API不兼容,因此此API仅通过浏览器命名空间提供。
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)
- fontSettings API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/fontSettings/
该API允许扩展管理某些字体设置,以依赖于特定的通用字体族和语言脚本。
chrome.fontSettings.getFont({
genericFamily: 'standard',
script: 'Egyp'
}, (details) => {});
chrome.fontSettings.setFont({
genericFamily: 'serif',
script: 'Jpan',
fontId: 'Comic Sans'
});
内容设置(Content Settings)
- contentSettings API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/contentSettings/
此API允许您按站点而不是全局自定义浏览器的行为:启用或禁用Cookie、JavaScript和插件。以下每个属性都有get()、set()和clear()方法:
- automaticDownloads(自动下载)
- camera(摄像头)
- cookies(Cookie)
- fullscreen(全屏)
- images(图像)
- javascript(JavaScript)
- location(位置)
- microphone(麦克风)
- mouselock(鼠标锁定)
- notifications(通知)
- plugins(插件)
- popups(弹出窗口)
- unsandboxedPlugins(非沙盒插件)
Cookies(Cookie)
- cookies API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/cookies/
- cookies API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/cookies
chrome.cookies API是浏览器Cookie的创建/读取/更新/销毁接口。
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)
- bookmarks API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/bookmarks/
- bookmarks API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks
chrome.bookmarks API是浏览器书签的创建/读取/更新/销毁接口。它包括管理书签层次结构的方法。
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是浏览器浏览历史的创建/读取/更新/销毁接口。
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)
- downloads API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/downloads/
- downloads API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/downloads
chrome.downloads API是浏览器下载的创建/读取/更新/销毁接口。“创建”下载意味着强制浏览器从指定URL下载。
// 开始下载
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)
- topSites API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/topSites/
- topSites API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/topSites
此API允许扩展读取显示在新标签页上的“常用网站”(访问最多的网站)。
const topSites = await chrome.topSites.get();
Browsing Data(浏览数据)
- browsingData API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/browsingData/
- browsingData API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browsingData
此API允许扩展程序以编程方式删除浏览数据,涵盖多个类别。
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(会话)
- sessions API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/sessions/
- sessions API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/sessions
此API允许扩展程序以编程方式查看并重新打开最近关闭的标签页。
const recentlyClosed =
await chrome.sessions.getRecentlyClosed();
// 恢复最近关闭的标签页
chrome.sessions.restore();
Tabs and Windows(标签页和窗口)
- tabs API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/tabs/
- tabs API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs
- windows API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/windows/
- windows API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/windows
- tabGroups API – Chrome Developers: https://developer.chrome.com/docs/extensions/reference/tabGroups/
这些API允许浏览器完全控制出现在浏览器内部的标签页和窗口。它可以执行创建、删除、检查、修改、重新排列、固定和静音等任务。
// 获取当前活动标签页
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" });
调试器
- debugger API - Chrome Developers: https://developer.chrome.com/docs/extensions/reference/debugger/
chrome.debugger API允许您以编程方式控制浏览器的调试器。使用它,您可以执行Devtools API能够执行的几乎所有操作,包括查询响应体(前提是浏览器的开发者工具界面未打开)。
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'
});
搜索
- search API - Chrome Developers: https://developer.chrome.com/docs/extensions/reference/search/
此API允许您以编程方式在浏览器的默认搜索引擎中执行搜索。
chrome.search.query({
disposition: "NEW_TAB",
text: "wikipedia"
});
闹钟
- alarms API - Chrome Developers: https://developer.chrome.com/docs/extensions/reference/alarms/
- alarms API - MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/alarms
此API用于安排在未来运行的代码。它在概念上类似于setTimeout()和setInterval(),但它能够唤醒服务工作者。
// 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) => {});
脚本
- scripting API - Chrome Developers: https://developer.chrome.com/docs/extensions/reference/scripting/
- scripting API - MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting
此API用于以编程方式将JavaScript或CSS注入页面。
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
- dom API – Chrome 开发者文档: https://developer.chrome.com/docs/extensions/reference/dom/ dom API 只有一个方法 openOrClosedShadowRoot(),用于获取指定元素托管的开放或封闭的 shadow root。 chrome.dom.openOrClosedShadowRoot(el);
文本转语音
- tts API – Chrome 开发者文档: https://developer.chrome.com/docs/extensions/reference/tts
tts API 允许你指示浏览器使用其原生文本转语音引擎大声朗读文本。
// 浏览器将大声朗读文本
chrome.tts.speak('Foo', {'lang': 'en-US', 'rate': 2.0});
// 等待之前的语音播放完成
chrome.tts.speak('Bar', {'enqueue': true});
// 立即停止语音
chrome.tts.stop();
隐私
- privacy API – Chrome 开发者文档: https://developer.chrome.com/docs/extensions/reference/privacy/
此 API 允许扩展程序获取和设置用户的隐私控制。
chrome.privacy.services.searchSuggestEnabled.get({}, (details) => {
if (details.levelOfControl === 'controllable_by_this_extension') {
chrome.privacy.services.searchSuggestEnabled.set({ value: true });
}
});
空闲
此 API 指示主机系统何时处于空闲状态。
// 每30秒检查一次系统状态
chrome.idle.queryState(30);
chrome.idle.onStateChanged.addListener(() => {});
开发者工具
- Devtools API – Chrome 开发者文档: https://developer.chrome.com/docs/extensions/mv3/devtools/
- Devtools API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Extending_the_developer_tools Devtools API 允许你向浏览器的开发者工具界面添加自定义接口。这些接口被授予仅可从开发者工具内部访问的 API 的特殊访问权限。
// 创建开发者工具面板
chrome.devtools.panels.create("Panel title", "path/to/icon.png", "panel.html");
// 嗅探活动页面的流量
chrome.devtools.network.onNavigated.addListener((url) => {});
注意: 此主题在 Devtools Pages 章节中有所涵盖。
扩展程序内省
- extension API – Chrome 开发者文档: https://developer.chrome.com/docs/extensions/reference/extension/
- extension API – MDN: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/extension 此 API 是一组实用程序。许多方法可用于检查运行中的扩展程序的内部配置。
const popupUrl = chrome.extension.getURL("popup.html");
const allViews = chrome.extension.getViews();
const popups = chrome.extension.getViews({ type: "popup" });
扩展程序管理
- management API – Chrome 开发者文档: https://developer.chrome.com/docs/extensions/reference/management/
- runtime API – Chrome 开发者文档: https://developer.chrome.com/docs/extensions/reference/runtime/ 扩展程序能够控制自身操作的基本功能,包括重新加载扩展程序、检查更新、自行卸载以及设置卸载 URL。
const selfInfo = chrome.management.getSelf();
// 卸载运行中的扩展程序
chrome.management.uninstallSelf();
const manifest = chrome.runtime.getManifest();
// 重新加载扩展程序
chrome.runtime.reload();
// 指定卸载后将用户引导到的 URL
chrome.runtime.setUninstallURL("https://www.wikipedia.org");
系统状态
- system APIs – Chrome 开发者文档:
- https://developer.chrome.com/docs/extensions/reference/system_cpu/
- https://developer.chrome.com/docs/extensions/reference/system_display/
- https://developer.chrome.com/docs/extensions/reference/system_memory/
- https://developer.chrome.com/docs/extensions/reference/system_storage/ system API 允许你检查主机操作系统的某些详细信息。cpu、display、memory 和 storage 属性都是 getter,它们返回一个由主机系统提供的 JavaScript 对象。
仅企业版可用 以下 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 所需的权限,以及管理扩展程序权限的最佳方式。