系统通知 Notification
本教程共 45 篇 · 第 21 篇 · 更新于 2026-08-03
21. 系统通知 Notification
本节目标
- 在主进程用 Notification 创建通知并 show
- 监听显示、点击、关闭、失败事件
- 了解渲染进程 Web Notifications API 的用法
- 掌握 macOS、Windows 的平台要求
桌面通知就是屏幕右下角弹出的那条提示:新消息来了、下载完成了、后台任务跑完了。Electron 提供 Notification 模块,让你直接调用操作系统原生的通知能力,而不是自己画一个假的。
本章讲主进程里如何创建通知、设置标题与正文、监听显示和点击,并说明各平台的特殊要求。渲染进程也能用 Web Notifications API,我们一并点一下。
21-1 在主进程创建一条通知
Notification 在主进程使用。实例化后必须手动调用 show(),通知才会出现——这一点和 Web 的 new Notification() 自动显示不同,要留意。
// main.js(主进程)
const { app, Notification } = require('electron/main')
app.whenReady().then(() => {
const n = new Notification({
title: '新消息',
body: '你有一条来自好友的留言'
})
n.show()
})
title 是通知顶部的大标题,body 是下面的正文。macOS 还支持 subtitle(副标题)。只传 title 也能弹,但配上文案体验更好。
21-2 监听显示与点击
通知对象是个事件发射器,常用事件有 show(显示时)、click(被点击)、close(被关闭)。比如点击通知时把窗口提到前台:
const n = new Notification({
title: '下载完成',
body: '文件已保存到下载目录'
})
n.on('show', () => console.log('通知已显示'))
n.on('click', () => {
console.log('用户点击了通知')
if (mainWindow) mainWindow.show()
})
n.on('close', () => console.log('通知关闭'))
n.show()
在 macOS 和 Windows 上,failed 事件会在创建或显示失败时触发,回调带错误信息;macOS 未签名时尤其容易走到这里(见下节)。开发时可监听它排查问题。
21-3 先判断是否支持
并非所有环境都保证支持通知。发之前用 Notification.isSupported() 探一下,避免在不支持的平台上做无效操作。
if (Notification.isSupported()) {
new Notification({ title: '提示', body: '当前系统支持通知' }).show()
} else {
console.log('当前系统不支持桌面通知')
}
21-4 渲染进程用 Web Notifications API
如果通知逻辑写在页面里,可以直接用标准的 Web Notifications API(window.Notification)。它走的是浏览器那套,不需要 IPC 回主进程。
// 渲染进程脚本
new window.Notification('来自渲染进程', {
body: '点击我会在控制台打印'
}).onclick = () => console.log('通知被点击')
官方建议:若从渲染进程发通知,优先用这套 Web API。只有需要调用系统底层细节(如 macOS 的 reply 内联回复)时,才回到主进程的 Notification 模块。
21-5 平台要求与差异
平台差异主要集中在 macOS 和 Windows。macOS 的通知基于 UNNotification 框架,要求应用经过代码签名,通知事件才会正常触发。未签名的开发构建会走到 failed 事件,这是系统限制,不是代码 bug。
Windows 上,开发期通知可能不显示,原因常是缺少开始菜单快捷方式对应的 AppUserModelID。Electron 在配合 Squirrel 打包时会自动处理好;开发时可手动调用 app.setAppUserModelId(process.execPath) 临时解决。另外 macOS 通知正文限制在 256 字节,超出会被截断。
Linux 则通过 libnotify 投递,只要桌面环境遵循 freedesktop 通知规范(GNOME、KDE、Unity 等)即可正常显示,基本无需额外配置。
21-6 带操作按钮与内联回复
macOS 和 Windows 的 Notification 支持更丰富的交互。actions 可加按钮,用户点击会触发 action 事件并带上按钮索引;hasReply 能开启内联回复框,提交后触发 reply 事件。
const n = new Notification({
title: '新留言',
body: '有人评论了你的动态',
actions: [{ type: 'button', text: '查看' }],
hasReply: true,
replyPlaceholder: '回复内容…'
})
n.on('action', (e) => console.log('点了按钮', e.actionIndex))
n.on('reply', (e) => console.log('回复:', e.reply))
n.show()
macOS 上这些能力依赖应用已签名;未签名时相关事件不会正常触发。功能虽强,但别滥用——通知应简洁,操作选项以一两个为宜。
21-7 权限与静音控制
远程内容想申请通知权限时,主进程应通过 session.setPermissionRequestHandler 把关,只允许可信来源。不要默认放行所有权限请求,那是安全隐患。
const { session } = require('electron/main')
const { URL } = require('node:url')
session.defaultSession.setPermissionRequestHandler((webContents, permission, cb) => {
if (permission === 'notifications' && new URL(webContents.getURL()).host === 'example.com') {
cb(true)
} else {
cb(false)
}
})
另外通知可设 silent: true 关闭提示音,设 timeoutType: 'never'(Linux/Windows)让通知常驻不自动消失。按需使用,避免打扰用户。
21-8 通知的标识与分组
macOS 和 Windows 的 Notification 支持 id 与 groupId。id 是唯一标识,配合 Notification.remove(id) 可删除指定通知;groupId 把相关通知在通知中心归为一组,适合聊天会话这类场景。
const { Notification } = require('electron/main')
const n = new Notification({
id: 'msg-42',
groupId: 'chat-thread-1',
title: '新消息',
body: '来自群聊的消息'
})
n.show()
macOS 还可通过 Notification.getHistory() 取回上次会话留下、仍在通知中心的通知,重新绑定事件处理器。这些能力都需要应用已签名。普通桌面提示用不到这么细,但做消息类应用时会很有用。
21-9 完整示例:任务完成的通知
把判断支持、创建、点击唤起窗口串起来,下面是一个后台任务完成时发通知的骨架。点击通知会把主窗口带到前台,给用户明确反馈。
// main.js(主进程)
const { app, BrowserWindow, Notification } = require('electron/main')
function notifyDone(mainWindow) {
if (!Notification.isSupported()) return
const n = new Notification({
title: '任务完成',
body: '文件处理已结束,点击查看结果'
})
n.on('click', () => {
if (mainWindow) {
mainWindow.show()
mainWindow.focus()
}
})
n.show()
}
通知文案要短、动作要明确。点击后通常把应用窗口前置或跳到对应页面,而不是只打一行日志。这样通知才真正成为「交互入口」,而不只是被动提示。
通知设计的小建议
通知要用得克制。它本质是「打断用户」的手段,发得太频繁会变成噪音。原则是:只通知用户真正需要马上知道的事,比如下载完成、收到重要消息、后台任务出错。
文案要短,标题一句话点明主题,正文补一句细节即可。点击通知应当有去处——把窗口前置、跳到对应页面,而不是只打日志。没有后续动作的通知,对用户价值很低。
还要注意平台限制。macOS 需签名、Windows 开发期需 AppUserModelID、正文有长度上限。上线前在三个系统各测一遍,别等用户反馈才发现通知根本不弹。
小结补充
再补一句:通知虽好,但滥用会适得其反。统计显示,用户对频繁弹窗的耐受度很低。上线前最好提供「关闭通知」的设置项,把主动权交还给用户。这既是礼貌,也能降低被系统判定为骚扰、从而被静音的风险。
小结
桌面通知用 Notification(主进程)或 Web Notifications API(渲染进程)。主进程写法要记得 new Notification(...).show() 手动触发,并可用 show/click/close/failed 事件响应交互。
发之前用 isSupported() 探一下更稳。平台方面:macOS 需代码签名、Windows 要 AppUserModelID、Linux 走 libnotify。按这些要求准备,通知才能可靠弹出。