跳转到内容

安装 · API

Badging API

发布于

有限可用不支持的浏览器: Chrome (Android)、Firefox (Desktop)W3C 草案

Badging API(navigator.setAppBadge() 与 navigator.clearAppBadge(),service worker 内的 WorkerNavigator 上同样暴露)在已安装 web 应用位于任务栏、Dock 或主屏幕的图标上显示一个数字或一个圆点。Chrome 81 与 Edge 81 在 Windows、macOS、ChromeOS 上绘制它;Safari 16.4 为 iOS 主屏幕 web 应用绘制,Safari 17 为 macOS Dock web 应用绘制;Android 上的 Chrome 84 与 Samsung Internet 13 只对已安装应用、且启动器支持角标时生效;Firefox 没有实现(BCD api.Navigator.setAppBadge)。

await navigator.setAppBadge(); // 一个圆点("flag"),不带数字
await navigator.setAppBadge(contents); // 一个数字;0 表示清除
await navigator.clearAppBadge(); // 移除角标
// service worker 内,例如在 push 处理器中
self.navigator.setAppBadge(count);

两个方法都返回 Promise<void>,在请求交给操作系统后兑现,而不是在角标可见时。Chromium 上不涉及权限提示;iOS 上只有用户允许了已安装应用的通知之后才会绘制角标。

只有 setAppBadge() 接受参数。

名称 类型 说明
contents unsigned long long,可选 要显示的数字。0 清除角标,等同于 clearAppBadge()。省略时角标是一个不带数字的圆点。大数字如何显示由操作系统决定;规范把该值称为提示,允许平台缩写。

setAppBadge() 在两种情形下拒绝或抛出,在另外两种情形下静默无效。

  • TypeError:contents 为负数、小数,或超出 [EnforceRange] unsigned long long 的范围。类型转换发生在创建 Promise 之前,因此 Chromium 中该错误是同步抛出的:Failed to execute 'setAppBadge' on 'Navigator': Value is outside the 'unsigned long long' value range.。
  • InvalidStateError:调用方文档不处于 fully active 状态(例如已脱离文档的 iframe),这是规范中两个方法的第一步。
  • 无错误、无角标:应用未安装。Chromium 在普通标签页中兑现 Promise 但不绘制任何东西,所以角标只在安装后可见。
  • 无错误、无角标:iOS 16.4 及以后,主屏幕 web 应用尚未获得通知权限(兼容性数据集备注)。调用兑现,图标保持原样。

Firefox 中 navigator.setAppBadge 为 undefined,未加保护的调用在触及 API 之前就会抛出 TypeError。

第一个示例运行在 service worker 中;第二个运行在页面中,并覆盖没有该 API 的浏览器。

把 push 事件里的未读数同步到图标

Section titled “把 push 事件里的未读数同步到图标”

推送载荷若携带服务端的未读数,可以在用户打开应用之前就更新图标。event.waitUntil() 让 worker 存活到角标调用落定;在页面显示收件箱时调用 clearAppBadge(),可以保证图标与实际一致。

sw.js
self.addEventListener('push', (event) => {
const data = event.data?.json() ?? {};
const unread = Number.isInteger(data.unread) ? data.unread : 0;
event.waitUntil(Promise.all([
self.registration.showNotification(data.title ?? 'New message'),
self.navigator.setAppBadge(unread),
]));
});
// page.js,在显示收件箱视图时
navigator.clearAppBadge?.();

在 Chromium 上只设角标而不显示通知是允许的,但在 iOS 上,不显示通知的 push 事件可能让应用失去推送订阅,所以上面的通知调用在 iOS 上不可省略。

缺少 setAppBadge 时,唯一能跨浏览器承载计数的界面是标签页标题。下面的回退把计数作为前缀加到标题上,计数为零时去掉前缀。

function showUnread(count) {
if ('setAppBadge' in navigator) {
return count > 0 ? navigator.setAppBadge(count) : navigator.clearAppBadge();
}
// 没有 Badging API(Firefox,或任何浏览器的普通标签页):改用标题。
const base = document.title.replace(/^\(\d+\) /, '');
document.title = count > 0 ? `(${count}) ${base}` : base;
return Promise.resolve();
}

标题回退只在标签页打开期间可见,这正是 Badging API 消除的限制;对 Firefox 用户来说,这仍然比什么都不显示更合适。

规范

规范状态
Badging API(角标)W3C 草案
  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Android)部分支持84中来源1
Chrome (Desktop)支持81中来源—
Edge (Desktop)支持81中来源—
Safari (iOS)支持16.4中来源2
Safari (macOS)支持17中来源—
Firefox (Desktop)不支持—中来源3
Samsung Internet部分支持13.0中来源4
  1. 角标仅对已安装应用生效,且取决于启动器是否支持。
  2. 仅限主屏幕 Web 应用;与通知权限绑定。
  3. Firefox 没有实现 Badging API;`navigator.setAppBadge` 为 undefined(MDN 兼容性表,2026-10-03 核对)。
  4. 与 Chrome for Android 一致:角标仅对已安装 Web 应用显示,且取决于启动器是否支持。

源数据: /compatibility/badging-api.json · 全球使用占比: 73 % (StatCounter 2026-05)

来源: 规范 · MDN · 最近核验 2026-06-24 · 置信度: 中 (由来源计算)