配了三年 Web Push,每次在 Notification.requestPermission() 里拿 granted 就直接调订阅接口——今天 Chrome 155 把这件事从根上变了
配了三年 Web Push,每次在 Notification.requestPermission() 里拿 granted 就直接调订阅接口——今天 Chrome 155 把这件事从根上变了。
Chrome 155 for Android 带了一个非阻塞通知权限 prompt:用户可以无视弹窗,窗口自动消失。但这个看似“更好用”的改动背后,有个坑你没注意——超时返回的状态值变了。
旧逻辑: 弹窗被用户无视或关掉,Notification.requestPermission() resolve 为 denied。开发者看到这个值,知道“没戏了”,直接展示引导用户去设置的提示。
新逻辑: 弹窗自动超时后,Notification.requestPermission() resolve 为 default——意思是“还没决定”。这意味着你的老代码看到 default 可能会再弹一次 prompt,或者以为没权限就放弃了,而不是等待用户从 Site Controls 里打开。
还有一个你没覆盖的路径:用户可以在网站控件菜单里随时订阅通知,不需要再碰原 prompt。这意味着权限状态可能在你没调用 requestPermission() 的情况下变成 granted。你原来的代码如果只在 Promise resolve 后调订阅接口,这个异步状态变化就被漏掉了。
// ❌ 旧写法——超时后拿到 default,你可能以为没权限就放弃了
Notification.requestPermission().then((permission) => {
if (permission === 'granted') {
subscribeToPushNotifications();
}
});
// ✅ 新写法——补上 Site Controls 的异步订阅路径
navigator.permissions.query({ name: 'notifications' })
.then((permissionStatus) => {
if (permissionStatus.state === 'granted') {
subscribeToPushNotifications();
}
// 用户从 Site Controls 打开通知权限会触发这个
permissionStatus.onchange = () => {
if (permissionStatus.state === 'granted') {
subscribeToPushNotifications();
}
};
});
Chrome 这次改的真正意图是让你按情境请求通知权限:电子商务在用户下单后请求,新闻网站在用户读了几篇后提示,旅游网站在用户搜完航班后建议。不是页面一加载就弹。
怎么迁:
- 把权限检查换成
navigator.permissions.query() - 加
onchange监听 Site Controls 的异步授权 - 把请求时机绑到真实用户行为上,而不是 load 事件
- 旧的
Notification.requestPermission().then()保留,但去掉“没拿到 granted 就展示设置引导”的逻辑——default现在只是“还没决定”,不是“拒绝了”
这件事本质是浏览器在把通知权限从“一次决定”变成“随时可改”的状态流,你的代码也得跟着从“请求-响应”模型切换到“订阅-监听”模型。
评论区
0 条评论
登录后可评论。