跳转到内容

能力 · API

registerProtocolHandler() 与 manifest 协议处理程序

发布于

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

把 Web 应用注册为 mailto: 或 web+music: 这类 URL 协议的处理程序,有两条路。navigator.registerProtocolHandler(scheme, url) 由页面发起、向用户弹出询问,在普通标签页里就能用;manifest 的 protocol_handlers 成员在 PWA 安装时向操作系统注册,不需要页面发起任何提示。两者都执行 HTML 标准的「normalize protocol handler parameters」步骤,所以协议与 URL 的规则完全一致:方法会抛异常的值,在 manifest 里会被静默丢弃。

registerProtocolHandler() 在桌面端 Firefox 2 与 Chrome 13 起就有,Edge 79 与 Opera 11.6 跟进;Chrome 77 起 url 只接受 http: 与 https:。Safari 没有实现,Android 上没有任何浏览器暴露它(BCD api.Navigator.registerProtocolHandler)。unregisterProtocolHandler() 只存在于 Chromium,始于 Chrome 38。manifest 成员是 Chrome 96 与 Edge 96 的桌面专属功能,完整支持情况见兼容性表。

navigator.registerProtocolHandler(scheme, url)
navigator.unregisterProtocolHandler(scheme, url)
{
"protocol_handlers": [
{ "protocol": "web+music", "url": "/play?song=%s" }
]
}

两个方法都返回 undefined。注册在调用返回后并行进行,没有可等待的 Promise,也无法得知用户是否接受了提示。两者都带 [SecureContext],url 的同源要求本身也蕴含了这一点。激活带已注册协议的链接时,浏览器把完整链接做百分号编码、替换掉 %s,然后在新的顶层浏览上下文中导航到结果。

方法参数与 manifest 条目成员一一对应。

方法参数 manifest 成员 类型 必填 说明
scheme protocol DOMString 是 检查前先转小写。必须是安全名单内的协议,或以 web+ 开头后接一个或多个小写 ASCII 字母(web+music 可以,web+music2 与 web+ 不行)。末尾带冒号即无效。
url url DOMString 是 必须包含字面量 %s。方法按文档解析、成员按 manifest URL 解析;结果必须是文档同源的 http: 或 https: URL,manifest 还要求位于其 scope 之内。

安全名单内的协议是 bitcoin、ftp、ftps、geo、im、irc、ircs、magnet、mailto、matrix、mms、news、nntp、openpgp4fpr、sftp、sip、sms、smsto、ssh、tel、urn、webcal、wtai 与 xmpp。manifest 处理时会跳过缺少 protocol 或 url、规范化失败、超出 scope,或 url 与前面条目重复的项,并且不报告原因。

registerProtocolHandler() 与 unregisterProtocolHandler() 同步抛出。manifest 成员不抛任何异常,无效条目在处理阶段被丢弃。

异常 条件
SecurityError scheme 既不在安全名单内,也不是 web+ 加小写字母,包括带冒号的 "mailto:";解析后的 url 不是 http: 或 https:,或与文档不同源;浏览器拦截了注册,例如注册 http 本身。Chrome 还会在 Isolated Web App 中抛出,并提示改用 manifest 成员。
SyntaxError url 不含 %s;url 解析失败,%s 位于 host 或端口时必然如此。

示例为部署在 https://player.example/ 的播放器注册 web+music。处理路由是 /play?song=%s,点击 web+music:track/42 会在该源打开 /play,song 参数经 URLSearchParams 解码后仍是 web+music:track/42。

在设置页提供注册入口并给出手动回退

Section titled “在设置页提供注册入口并给出手动回退”

先检测方法是否存在,再同时捕获两个异常名:这里的 SecurityError 多半是协议名写错,而用户拒绝提示时页面根本不会知道。Safari 和所有 Android 浏览器走回退分支,向用户说明如何改为粘贴链接。

const button = document.querySelector("#register-handler");
if (typeof navigator.registerProtocolHandler !== "function") {
button.hidden = true;
document.querySelector("#paste-link-help").hidden = false;
} else {
button.addEventListener("click", () => {
try {
navigator.registerProtocolHandler("web+music", "/play?song=%s");
button.textContent = "已请求,请在浏览器提示中确认";
} catch (err) {
if (err.name === "SecurityError" || err.name === "SyntaxError") {
console.error(`${err.name}: ${err.message}`);
} else {
throw err;
}
}
});
}

HTML 标准要求浏览器记住被拒绝的注册、不再重复提示,所以拒绝后再点一次可能毫无反应;在按钮的帮助文字里把这一点说清楚。

在 manifest 中声明同一处理程序并读取启动 URL

Section titled “在 manifest 中声明同一处理程序并读取启动 URL”

manifest 带上该条目后,已安装的用户无需提示即可获得关联。路由在 song 查询参数里收到整条链接(含协议),需要自己去掉前缀。

{
"name": "Player",
"start_url": "/",
"scope": "/",
"protocol_handlers": [
{ "protocol": "web+music", "url": "/play?song=%s" }
]
}
const launched = new URL(location.href).searchParams.get("song");
if (launched && launched.startsWith("web+music:")) {
const trackId = launched.slice("web+music:".length); // "track/42"
loadTrack(trackId);
} else {
showLibrary(); // 直接打开,而不是通过协议链接
}

路由要放在 manifest 的 scope 之内:超出 scope 的 url 会从处理后的 manifest 中被丢弃,安装照常完成,却没有处理程序,也没有任何警告。

unregisterProtocolHandler() 接受同样的两个参数,只存在于 Chromium。要和 registerProtocolHandler() 分开检测,因为 Firefox 有前者没有后者。

function forgetHandler() {
if (typeof navigator.unregisterProtocolHandler !== "function") {
return false; // Firefox:只能在浏览器自己的设置里移除
}
navigator.unregisterProtocolHandler("web+music", "/play?song=%s");
return true;
}

通过方法取消注册不影响 manifest 建立的关联;那一份随已安装应用一起移除。

规范

规范状态
清单协议处理器(protocol_handlers)W3C
HTML Standard: registerProtocolHandler() methodWHATWG 现行标准
HTML Standard: normalize protocol handler parametersWHATWG 现行标准
Web App Manifest incubations: protocol_handlers memberWICG 草案
  • 图例
  • 支持
  • 部分支持
  • 需开启标志
  • 不支持
  • 未知
浏览器 / 平台支持版本置信度来源备注
Chrome (Android)不支持—中来源1
Chrome (Desktop)支持96中来源—
Edge (Desktop)支持96中来源—
Safari (iOS)不支持—中来源2
Safari (macOS)不支持—中来源3
Firefox (Desktop)不支持—中来源4
Samsung Internet不支持—中来源5
  1. 仅桌面端可注册。
  2. Safari 未实现 `protocol_handlers` manifest 成员(MDN 兼容性表,2026-10-03 核对)。
  3. Safari 未实现 `protocol_handlers` manifest 成员(MDN 兼容性表,2026-10-03 核对)。
  4. 桌面版 Firefox 不依据 manifest 安装 Web 应用,也未实现 `protocol_handlers`(MDN 兼容性表,2026-10-03 核对)。
  5. Chromium 仅在桌面安装中提供 manifest 协议处理程序;Samsung Internet 未列出支持(MDN 兼容性表,2026-10-03 核对)。

源数据: /compatibility/protocol-handlers.json · 全球使用占比: 37 % (StatCounter 2026-05)

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