Manage events with background scripts(使用后台脚本管理事件)
警告
您正在查看的页面描述了使用 Manifest V2 的扩展。现在 Manifest V3 已经发布,我们强烈建议您将它用于您创建的任何新扩展。
扩展程序是基于事件的程序,用于修改或增强 Chrome 浏览体验。事件是浏览器触发器,例如导航到新页面、移除书签或关闭选项卡。扩展在它们的后台脚本中监视这些事件,然后对指定的指令做出反应。
后台页面在需要时加载,空闲时卸载。一些事件示例包括:
- 扩展程序首先安装或更新到新版本。
- 后台页面正在侦听一个事件,并且该事件被调度。
- 内容脚本或其他扩展程序发送消息sends a message.。
- 扩展中的另一个视图(例如弹出窗口)调用
runtime.getBackgroundPage
。
加载完成后,只要后台页面正在执行操作(例如调用 Chrome API 或发出网络请求),它就会一直运行。此外,在所有可见视图和所有消息端口都关闭之前,后台页面不会卸载。请注意,打开视图不会导致事件页面加载,但只会阻止它在加载后关闭。
有效的后台脚本会一直处于休眠状态,直到它们监听的事件发生,对指定的指令做出反应,然后卸载。
# Register background scripts(注册后台脚本)
后台脚本在清单(manifest)中的“background”
字段下注册。它们列在“scripts”
键之后的数组中,“persistent”
应指定为 false
。
{
"name": "Awesome Test Extension",
...
"background": {
"scripts": ["background.js"],
"persistent": false
},
...
}
可以为模块化代码注册多个后台脚本。
{
"name": "Awesome Test Extension",
...
"background": {
"scripts": [
"backgroundContextMenus.js",
"backgroundOmniBox.js",
"backgroundOauth.js"
],
"persistent": false
},
...
}
警告
保持后台脚本持续活动的唯一情况是扩展程序使用 chrome.webRequest API 来阻止或修改网络请求。 webRequest API 与非持久性后台页面不兼容。
如果扩展程序当前使用持久性后台页面,请参阅后台迁移指南以获取有关如何切换到非持久性模型的说明。
# Initialize the extension(初始化扩展)
侦听 runtime.onInstalled
事件以在安装时初始化扩展。使用此事件设置状态或一次性初始化,例如上下文菜单context menu。
chrome.runtime.onInstalled.addListener(function() {
chrome.contextMenus.create({
"id": "sampleContextMenu",
"title": "Sample Context Menu",
"contexts": ["selection"]
});
});
# Set up listeners(设置监听器)
围绕扩展所依赖的事件构建后台脚本。定义功能相关的事件允许后台脚本处于休眠状态,直到这些事件被触发并防止扩展丢失重要的触发器。
监听器必须从页面开始同步注册。
chrome.runtime.onInstalled.addListener(function() {
chrome.contextMenus.create({
"id": "sampleContextMenu",
"title": "Sample Context Menu",
"contexts": ["selection"]
});
});
// This will run when a bookmark is created.
chrome.bookmarks.onCreated.addListener(function() {
// do something
});
不要异步注册侦听器,因为它们不会被正确触发。
chrome.runtime.onInstalled.addListener(function() {
// ERROR! Events must be registered synchronously from the start of
// the page.
chrome.bookmarks.onCreated.addListener(function() {
// do something
});
});
扩展可以通过调用 removeListener 从其后台脚本中删除侦听器。如果某个事件的所有侦听器都被删除,Chrome 将不再为该事件加载扩展程序的后台脚本。
chrome.runtime.onMessage.addListener(function(message, sender, reply) {
chrome.runtime.onMessage.removeListener(event);
});
# Filter events(过滤事件)
使用支持事件过滤器event filters的 API 将侦听器限制为扩展所关心的情况。如果扩展程序正在侦听 tabs.onUpdated
事件,请尝试使用带有过滤器的 webNavigation.onCompleted
事件,因为 tabs API 不支持过滤器。
chrome.webNavigation.onCompleted.addListener(function() {
alert("This is my favorite website!");
}, {url: [{urlMatches : 'https://www.google.com/'}]});
# React to listeners(对监听作出反应)
一旦事件被触发,监听器就会触发功能。要对事件做出反应,请在侦听器事件内部构建所需的反应。
chrome.runtime.onMessage.addListener(function(message, callback) {
if (message.data == "setAlarm") {
chrome.alarms.create({delayInMinutes: 5})
} else if (message.data == "runLogic") {
chrome.tabs.executeScript({file: 'logic.js'});
} else if (message.data == "changeColor") {
chrome.tabs.executeScript(
{code: 'document.body.style.backgroundColor="orange"'});
};
});
# Unload background scripts(卸载后台脚本)
数据应该定期保存,这样如果扩展程序崩溃而没有收到 onSuspend
,重要信息就不会丢失。使用存储storage API 来帮助解决这个问题。
chrome.storage.local.set({variable: variableInformation});
如果扩展程序使用消息传递message passing,请确保关闭所有端口。在所有消息端口都关闭之前,后台脚本不会卸载。侦听 runtime.Port.onDisconnect 事件将深入了解开放端口何时关闭。使用 runtime.Port.disconnect 手动关闭它们。
chrome.runtime.onMessage.addListener(function(message, callback) {
if (message == 'hello') {
sendResponse({greeting: 'welcome!'})
} else if (message == 'goodbye') {
chrome.runtime.Port.disconnect();
}
});
后台脚本的生命周期可以通过监控扩展条目何时出现和从 Chrome 的任务管理器中消失来观察
通过单击 Chrome 菜单打开任务管理器,将鼠标悬停在更多工具上并选择“任务管理器”。
后台脚本在几秒钟不活动后自行卸载。如果需要任何最后一分钟的清理,请收听 runtime.onSuspend
事件。
chrome.runtime.onSuspend.addListener(function() {
console.log("Unloading.");
chrome.browserAction.setBadgeText({text: ""});
});
但是,持久化数据应该优于依赖 runtime.onSuspend
。它不允许进行尽可能多的清理,并且在发生崩溃时也无济于事。