
Notification 构造函数里 icon 参数必须是绝对路径或 CORS 允许的 URL
浏览器对 Notification 的 icon 字段有严格限制:相对路径(比如 "./icon.png")在很多情况下会静默失败,尤其当页面通过 file:// 协议打开,或服务端未正确设置 CORS 头时。根本原因不是图标格式不对,而是跨域资源加载被拦截——你看到通知弹出但没图标,大概率是控制台里藏着一条 Failed to load Resource: net::ERR_FAILED 或 Cross-Origin Read Blocking (CORB) 警告。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 用开发者工具的 Network 面板过滤
icon对应的请求,确认是否 404 或状态码为0 - 确保图标 URL 是完整协议+域名的绝对地址,例如
"https://example.com/assets/notify-icon.png",而非"assets/notify-icon.png" - 本地开发时,别直接双击 html 文件打开;启动一个本地服务器(如
python3 -m http.server 8000),让页面走http://localhost:8000 - 如果图标放在同域子路径下,用
new URL("./icon.png", import.meta.url).href(ESM 环境)或new URL("./icon.png", document.baseURI).href动态转成绝对路径,比硬写相对路径更可靠
chrome 和 firefox 对 icon 尺寸和格式的实际兼容性差异
文档说支持 PNG、JPEG、ICO,但真实情况是:Chrome 90+ 对非 PNG 图标容忍度变低,Firefox 则对尺寸不规范的 ICO 显示异常。最稳妥的组合是 192x192 或 256x256 的 PNG,带透明背景,无嵌入色域信息(避免 sRGB / Adobe RGB 混淆)。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 不要用
favicon.ico直接当通知图标——它通常是多尺寸合并的 ICO 文件,浏览器可能选错帧或解码失败 - 用 ImageMagick 命令快速生成标准图:
convert original.png -resize 192x192 -background none -gravity center -extent 192x192 notify-icon.png - 在
Notification.permission === "granted"后再调用构造函数,避免因权限未获准导致的初始化失败掩盖图标问题
Service Worker 环境下 showNotification 的 icon 路径不能用相对路径
从 Service Worker 调用 self.registration.showNotification() 时,icon 字段的解析上下文是 SW 脚本本身所在位置,不是当前网页。这意味着即使网页里 icon: "./icon.png" 能工作,SW 里写同样路径大概率 404——因为 SW 通常部署在根目录(如 /sw.js),而图标在 /assets/ 下。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 在 SW 中统一用绝对路径,如
icon: "/assets/notify-icon.png"(注意开头的/) - 如果图标路径需要动态拼接,优先用
self.location.origin + "/assets/...",而不是依赖location.href(SW 里没有location对象) - 测试时在 Chrome 的 Application → Service Workers 面板里点击 “Update on reload”,确保 SW 加载的是最新版本,否则旧缓存可能还在读错路径
图标不显示却无报错?检查 Notification 权限和安全上下文
有时候图标字段传了正确 URL,Network 也显示 200,但通知里依然空白。常见原因是页面未处于安全上下文(即非 https:// 或 localhost),此时 Chrome 会降级处理:允许通知弹出,但忽略 icon、badge 等视觉字段,且不抛任何错误。
实操建议:
立即学习“前端免费学习笔记(深入)”;
- 在地址栏看锁形图标是否亮起;开发阶段用
localhost完全没问题,但127.0.0.1在某些旧版 Chrome 里不算安全上下文 - 检查
document.hasStorageAccess()和document.featurePolicy.allowedFeatures(),部分企业环境会禁用通知相关能力 - 真机调试 ios safari 时,图标必须是 HTTPS 且尺寸精确匹配(Apple 强制要求
1024x1024PNG),否则直接忽略——这点和桌面端完全不同
图标路径看着简单,实际卡在协议、权限、上下文、尺寸四层嵌套判断里。少查一层,就只能看到一个光秃秃的通知框。