在开发Chrome插件时,我遇到一个小问题。最近在研究Chrome V3版本的插件,其中包含一个内容脚本,它需要在完成一系列操作之后发送系统通知消息,提醒用户已经完成。
然而,当我尝试在内容脚本中调用chrome.notifications API发送通知时,发现根本无法触发任何通知消息。根据文档,内容脚本似乎不具备直接发送系统通知的权限。那么,在Chrome V3插件的架构中,如果内容脚本需要发送通知消息,该如何实现呢?
解决思路
- 首先确定发送通知的API是
chrome.notifications.create
- 内容脚本通常没有直接访问Chrome API的权限,所以这个API通常是在背景脚本中调用
- 当直线行不通的时候,这时候咱们就要考虑一下曲线救插件的操作了,这时候我们可以让内容脚本发送消息到背景脚本,然后让背景脚本调用这个API
1、配置权限
首先,你需要在扩展的清单文件中声明 notifications
权限。这个权限允许扩展使用 chrome.notifications
API 生成桌面通知。
{
"permissions": [
"notifications"
]
}
一般情况下内容脚本和背景脚本都是通过消息传递机制通信,这时候内容脚本可以发送消息到背景脚本中,这个发送的消息,需要携带通知的标题和内容
因为发送给背景脚本的消息可能存在很多,这时候发送系统通知的消息就需要一个标记,也就是通信的类型。
2、内容脚本发送消息
在内容脚本中,你可以使用 chrome.runtime.sendMessage
来发送一个消息给背景脚本,请求它创建一个通知。例如:
// 内容脚本中的代码
chrome.runtime.sendMessage({
type: "createNotification",
title: "通知标题",
message: "这是通知的内容"
});
因为每次发送系统通知的类型是固定的,每次变化的是标题和内容,这时候就可以封装成一个方法,每次在内容脚本中调用方法就可以了,可以简化代码的书写
/**
* 发送系统消息到 Chrome 扩展的后台脚本
*
* @param {string} title - 消息的标题
* @param {string} message - 消息的内容
*/
export function sendSystemMessage(title, message) {
chrome.runtime.sendMessage({
action: messagesCon.TB_SEND_SYSTEM_MESSAGE,
title,
message
})
}
3、在背景脚本中处理通知请求
背景脚本需要监听从内容脚本发送的消息,并根据消息创建相应的通知。以下是背景脚本中的示例代码:
// 背景脚本中的代码
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.type === "createNotification") {
chrome.notifications.create(null, {
type: "basic",
iconUrl: "path/to/icon.png", // logo图片的位置
title: message.title,
message: message.message,
});
}
});
有时候我想获取到消息通知的结果,判断消息是否发送成功,这时候为了提高代码的通用性,就可以把消息封装成一个异步方法,并且可以增加一些额外的参数,封装后的代码如下所示:
/**
* 发送系统通知消息
*
* @param {string} title - 通知的标题。
* @param {string} message - 通知的内容。
* @param {string} [iconUrl] - 通知图标的 URL(可选),默认使用扩展的图标。
* @param {string} [type='basic'] - 通知类型,可选值包括 'basic', 'image', 'list', 'progress'。
* @returns {Promise<string>} 返回一个 Promise,当通知创建成功时,返回通知的 ID。
*/
export function sendSystemNotification(title, message, iconUrl = '', type = 'basic') {
return new Promise((resolve, reject) => {
// 创建通知的选项
const options = {
type: type,
iconUrl: iconUrl || chrome.runtime.getURL('icon.png'), // 默认使用扩展的图标
title: title,
message: message
}
// 创建通知
chrome.notifications.create(options, (notificationId) => {
if (chrome.runtime.lastError) {
return reject(chrome.runtime.lastError) // 如果创建失败,返回错误信息
}
resolve(notificationId) // 返回通知的 ID
})
})
}
通过上面的这种方式,就可以在内容脚本中发送系统通知了。但是请注意,在适当和必要时再发送通知,以避免打扰用户,从而提供良好的用户体验。