很遗憾,没有简单的方法来实现这个。当然没有预先确定协议处理程序是否已安装的方法。
正如您所提到的,
Internet Explorer具有
protocolLong
属性,但我无法使其返回除所有自定义协议处理程序之外的任何其他内容 - 如果有人知道如何让IE返回正确的值,请告诉我,以便我可以更新此部分。 我在IE中找到的最佳解决方案是
附加到用户代理字符串或安装浏览器扩展程序和你的应用程序一起公开JavaScript可访问属性。
Firefox是主要浏览器中最容易的,因为它允许您尝试并捕获失败的导航尝试。返回的错误对象包含一个名为
NS_ERROR_UNKNOWN_PROTOCOL
的
name
属性:
try {
iframe.contentWindow.location.href = "randomprotocolstring://test/";
} catch(e) {
if (e.name == "NS_ERROR_UNKNOWN_PROTOCOL")
window.location = "/download/";
}
Firefox会弹出自己的警告框:
Firefox不知道如何打开此地址,因为协议(randomprotocolstring)未与任何程序关联。
一旦关闭此框,catch
块将执行,您就有了一个可用的备选方案。
其次是Opera,它允许您利用可预测性法则来检测自定义协议链接的成功。如果自定义协议单击有效,则页面将保持相同位置。如果没有安装处理程序,则Opera将导航到错误页面。这使得使用iframe非常容易检测:
iframe.contentWindow.location = "randomprotocolstring://test/";
window.setTimeout(function () {
try {
alert(ifr.contentWindow.location);
} catch (e) { window.location = "/download/"; }
}, 0);
setTimeout
在这里是为了确保我们在导航后检查位置。需要注意的是,如果尝试访问页面,则 Opera 会抛出 ReferenceException(跨域安全错误)。不过这无关紧要,因为我们只需要知道位置已从 about:blank
更改,所以使用 try ... catch
就可以。
Chrome 在此方面官方上说很差。如果自定义协议处理程序失败,则完全没有反应。如果处理程序有效...你猜对了...仍然没有反应。恐怕没有办法区分两者。
我没有测试过 Safari,但我担心它与 Chrome 相同。
在调查此问题时,欢迎尝试我编写的测试代码(我自己也有兴趣)。它在 Opera 和 Firefox 上都兼容,但目前在 IE 和 Chrome 上没有任何作用。