Firefox 158 的 navigate 选项:通知点击后浏览器自己跳,不用再写 notificationclick
Web 通知一直有个没说破的约定:收到 push → showNotification → 用户点击 → 触发 notificationclick → 你在 Service Worker 里 openWindow。这条链路里,跳转目标其实早就在通知里确定了,可你还是要写一整个事件处理器把它取出来、再手动跳。
Firefox 158 给 Notification 加了一个 navigate 选项,把中间那一整段省掉了:构造通知时直接把 URL 交给浏览器,用户激活通知后浏览器自己导航,click / notificationclick 都不再触发。
老写法为什么要写这么多
推送分两种,跳转逻辑也跟着分叉:
- 页面内
new Notification(...)弹的(非持久化),点击走click事件; - Service Worker 里
showNotification(...)弹的(持久化),点击走notificationclick,还得event.waitUntil(clients.openWindow(url))。
SW 里的典型实现:
self.addEventListener("push", (event) => {
const d = event.data.json();
event.waitUntil(
self.registration.showNotification(d.title, {
body: d.body,
data: { url: d.url },
tag: "msg",
})
);
});
self.addEventListener("notificationclick", (event) => {
event.notification.close();
const url = event.notification.data.url;
event.waitUntil(
clients.matchAll({ type: "window" }).then((list) => {
for (const c of list) if (c.url === url && "focus" in c) return c.focus();
return clients.openWindow(url);
})
);
});
两个高频翻车点:URL 塞进 data 忘了取、matchAll 的匹配条件写歪,结果就是「通知点了但页面不动」。
新写法:URL 直接交给浏览器
Firefox 158 起加 navigate 即可,页面和 SW 同一种写法:
// 页面内
new Notification("Alice 发来一条消息", {
body: "中午一起吃饭?",
navigate: "/messages/alice",
});
// Service Worker 内
self.registration.showNotification("Alice 发来一条消息", {
body: "中午一起吃饭?",
navigate: "/messages/alice",
});
几个要点:
navigate的值相对页面 base URL 解析,可以写相对路径;- 设置了它之后,用户激活通知时浏览器直接导航,不再触发
click或notificationclick; - 该属性在 Web Worker 中可用;
- 只读属性
Notification.navigate返回解析后的绝对 URL,没设置时是空串,可用来在代码里确认。
前后对照:
- 过去:弹通知(带
data.url)→ 用户点击 → 触发事件 → 处理器取 URL →openWindow或focus→ 跳转。跨页面和 SW 两套写法,至少 5 步。 - 现在:弹通知(带
navigate)→ 用户点击 → 浏览器导航。1 步,同一套写法,也不再有「URL 存在 data 里没取出来」这种失败模式。
对「点了就去某页」的资讯推送、消息提醒,这能直接删掉一段易错代码。要点完先埋点、或按状态决定聚焦已有窗口还是开新窗口的复杂场景,仍应继续用事件处理器。
落地建议
- 翻一遍现有的
notificationclick:如果里面只是「取 data.url → openWindow/focus」,直接用navigate选项替换,删掉这段 SW 代码。 - 路径写法注意:相对路径按页面 base URL 解析,跨域跳转给绝对 URL。
- 兼容与降级:
navigate目前是实验性特性,仅 Firefox 158(Nightly)先行支持。上线保留notificationclick兜底,用if ("navigate" in Notification.prototype)决定走哪条路径。
(navigate 属实验性 API,生产环境务必保留事件处理器兜底。)
评论区
0 条评论
登录后可评论。