跳转到内容

安装中的概念

安装横幅与 beforeinstallprompt

发布于 更新于

有限可用不支持的浏览器: Firefox (Desktop)、Firefox (Android)、Safari (macOS)、Safari (iOS)WICG 草案

beforeinstallprompt 事件给 Chromium 页面一个只能使用一次的对象,应用自己的横幅或按钮可以借它打开浏览器安装提示。页面可以延后提示,但在收到事件、确认这条安装路径可用之前,应让自己的安装控件保持隐藏。

BCD api.BeforeInstallPromptEvent 把 Chrome 标为从 44 支持,把 Samsung Internet Android 标为从 5.0 支持;Edge 记录为 "mirror"。兼容性数据列出目标浏览器。BCD 未记录 Firefox 或 Safari 支持;其 api.BeforeInstallPromptEvent.prompt 条目把 Chrome 44 至 75 记录为部分实现,Promise 兑现时没有返回值,Chrome 76 起才记录结果对象。这个事件尚未标准化,在 Firefox 和 Safari 中不存在,因此安装横幅必须有明确的无事件路径。

在 window 上监听事件,调用 preventDefault(),保存事件对象,然后显示安装控件。在安装控件的点击处理器中调用 prompt()。MDN 指出,prompt() 必须在用户动作的处理器中调用,并且每个 BeforeInstallPromptEvent 只能调用一次。提示流程结束后应清除已保存的事件。代码需要覆盖 Chrome 44 至 75 时,应从 userChoice 读取结果,因为这些版本的 prompt() 不返回结果对象。

状态 横幅动作 页面获得的依据
事件尚未触发 隐藏程序化安装按钮 页面没有可用的提示对象
beforeinstallprompt 触发 保存事件并显示按钮 浏览器判定应用可使用这条安装流程
prompt() 结束 隐藏按钮并丢弃事件 userChoice 提供 "accepted" 或 "dismissed";Chrome 76 起 prompt() 本身才返回该结果对象
appinstalled 触发 隐藏安装推广并清除状态 浏览器报告应用已安装
没有事件 API 不调用 prompt(),改为显示浏览器对应的帮助 BCD 未记录 Firefox 或 Safari 支持 BeforeInstallPromptEvent

preventDefault() 控制支持浏览器中该事件的默认安装推广。Chrome 的 mini-infobar 更新说明,从 Chrome 76 起,这个调用可阻止 mini-infobar。页面横幅本身不会安装应用;它只是向用户提供控件,稍后由控件调用浏览器拥有的 prompt() 方法。

MDN 将 outcome 为 "accepted" 定义为用户安装了应用。还应监听 appinstalled,这样从保存事件之外的浏览器 UI 完成安装时也能撤下推广。MDN 安装指南也要求调用 prompt() 后清除已保存的事件,因为同一个事件不能再次使用。

应把事件对象和横幅当成同一份状态。导航会丢弃 JavaScript 对象,新的文档要等待自己的事件;用户拒绝提示后,这个对象也不再有用。MDN 的事件示例在 prompt() 返回后隐藏按钮并清除引用,appinstalled 示例则在用户从其他浏览器入口完成安装时做同样的清理。这样,页面不会留下仍然可见、却指向已经消耗或不存在事件的控件。

最终确认仍由浏览器负责。页面可以决定何时显示自己的推广,以及何时调用 prompt();在已记录的 Chrome 支持范围内,userChoice 会报告用户在浏览器 UI 中作出的选择。应用分析应读取该结果,不应使用页面自己的成功状态替代浏览器确认。当结果为 "dismissed" 时,撤下与本次事件对应的横幅,等待以后新的 beforeinstallprompt 事件重新建立状态。

BCD 对 Firefox 和 Safari 记录的是 version_added: false。特性检测可以选择说明文字,却不能生成浏览器安装提示。回退说明应保持简短,同时保留浏览器菜单或自带安装入口。

目标 Chromium 事件路径 无事件路径
显示页内安装操作 收到 beforeinstallprompt 后显示 保持隐藏
打开浏览器确认界面 在点击处理中调用已保存事件的 prompt() 说明浏览器从哪里提供安装入口
移除失效推广 处理 appinstalled,使用后清除事件 页面加载时重新检查已安装显示模式
处理用户拒绝 隐藏控件,等待新的事件 没有可读取的提示结果

横幅在 HTML 中默认隐藏。只有浏览器向页面交付有效事件对象后,JavaScript 才显示它。

等待 beforeinstallprompt 前,先检测窗口是否有对应的事件处理器属性。支持该事件时,安装按钮保持隐藏,直到事件触发;不支持时,代码改为显示浏览器安装说明。BCD 未记录 Firefox 或 Safari 支持 BeforeInstallPromptEvent。

<button data-event-install type="button" hidden>安装</button>
<p data-event-fallback hidden>如果浏览器提供安装命令,请从浏览器界面使用该命令。</p>
<script>
var installButton = document.querySelector('[data-event-install]');
var installFallback = document.querySelector('[data-event-fallback]');
if ('onbeforeinstallprompt' in window) {
window.addEventListener('beforeinstallprompt', function (event) {
event.preventDefault();
installButton.hidden = false;
});
} else {
installButton.hidden = true;
installFallback.hidden = false;
}
</script>

下一个示例会为支持分支补上点击处理器和提示流程。

下面是完整的 HTML 示例。它把浏览器事件保留到用户点击,从支持范围更广的 userChoice Promise 读取结果,不会解引用 prompt() 的返回值;appinstalled 触发时也会撤下横幅。

<aside data-install-banner hidden>
<p>安装此应用,以便更快打开。</p>
<button type="button">安装</button>
</aside>
<p><output data-install-status aria-live="polite"></output></p>
<script>
(function () {
var installEvent = null;
var banner = document.querySelector('[data-install-banner]');
var status = document.querySelector('[data-install-status]');
var installButton = banner && banner.querySelector('button');
if (!banner || !status || !installButton) return;
window.addEventListener('beforeinstallprompt', function (event) {
event.preventDefault();
installEvent = event;
installButton.disabled = false;
banner.hidden = false;
});
installButton.addEventListener('click', function () {
if (!installEvent) return;
var pendingEvent = installEvent;
installEvent = null;
installButton.disabled = true;
pendingEvent.prompt().then(function () {
return pendingEvent.userChoice;
}).then(function (choice) {
status.textContent = '安装提示结果:' + choice.outcome;
banner.hidden = true;
}, function (error) {
status.textContent = '无法打开安装提示:' + error.name;
banner.hidden = true;
});
});
window.addEventListener('appinstalled', function () {
installEvent = null;
banner.hidden = true;
status.textContent = '应用已安装。';
});
}());
</script>

按钮保持隐藏,直到事件真正触发;仅检测到属性不会改变这个状态。这使界面与浏览器对本次访问的判定保持一致。

失败路径会选择帮助说明,不会等待 BCD 在 Firefox 或 Safari 中未记录的事件。应用以 standalone 模式打开后,检查结果会隐藏说明。

<p data-install-help hidden>
如果浏览器提供安装命令,请从浏览器界面使用该命令。
</p>
<p data-installed-state hidden>此应用已经作为已安装应用打开。</p>
<script>
var help = document.querySelector('[data-install-help]');
var installedState = document.querySelector('[data-installed-state]');
var installed = window.matchMedia('(display-mode: standalone)').matches;
if (help && installedState) {
installedState.hidden = !installed;
help.hidden = installed || 'onbeforeinstallprompt' in window;
}
</script>

回退分支没有 BeforeInstallPromptEvent,所以不调用 prompt()。应根据已测试的浏览器界面调整提示文字。安装提示兼容性数据给出引擎层面的支持差异,iOS 安装 API 实验记录则单独保存实测行为。

此次更正使 "accepted" 结果的说明与引用来源保持一致。MDN 的 prompt() 参考将 "accepted" 定义为用户安装了应用,web.dev 的应用内安装指南说明 userChoice 可报告用户是否通过应用内界面完成安装。原 publishedAt 日期保持不变。

规范

规范状态
安装提示(beforeinstallprompt)WICG 草案
  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Desktop)#支持44高来源—
Chrome (Android)#支持44高来源1
Edge (Desktop)#支持79高来源2
Firefox (Desktop)#不支持—高来源3
Firefox (Android)#不支持—高来源45
Safari (macOS)#不支持—高来源6
Safari (iOS)#不支持—高来源78
Samsung Internet#支持5.0高来源—
WebView (Android)#支持44高来源9
  1. 由 browser-compat-data 镜像自 Chrome 的数据推导。
  2. 由 browser-compat-data 镜像自 Chrome 的数据推导。
  3. browser-compat-data 未记录 Firefox 的支持。
  4. browser-compat-data 未记录 Firefox for Android 的支持。
  5. 由 browser-compat-data 镜像自 Firefox 的数据推导。
  6. browser-compat-data 未记录 Safari 的支持。
  7. browser-compat-data 未记录 iOS 版 Safari 的支持。
  8. 由 browser-compat-data 镜像自 Safari 的数据推导。
  9. 由 browser-compat-data 镜像自 Chrome Android 的数据推导。

源数据: /compatibility/install-prompt.json · 全球使用占比: 75 % (StatCounter 2026-09, CC BY-SA 4.0)

来源: 规范 · MDN · 最近核验 2026-10-20 · 置信度: 高 (由来源计算)