我们正在使用注册自己协议的软件。我们可以从浏览器然后通过链接运行应用程序,如:
customprotocol://do_this.
但是有没有办法检查用户系统是否支持这种自定义协议?如果没有,我们想请用户先安装软件。
例如:
if (canHandle ('customprotocol')) {
// run software
}
else {
// ask to install
}
编辑 我知道 protocolLong 属性,但它仅适用于 IE。
我们正在使用注册自己协议的软件。我们可以从浏览器然后通过链接运行应用程序,如:
customprotocol://do_this.
但是有没有办法检查用户系统是否支持这种自定义协议?如果没有,我们想请用户先安装软件。
例如:
if (canHandle ('customprotocol')) {
// run software
}
else {
// ask to install
}
编辑 我知道 protocolLong 属性,但它仅适用于 IE。
不幸的是,没有简单的方法可以实现这一目标。当然没有任何方法可以预先确定是否安装了协议处理程序。
正如您所提到的,Internet Explorer具有该protocolLong
属性,但我无法让它为所有自定义协议处理程序返回“未知协议”以外的任何内容——如果有人知道如何让 IE 返回正确的值,请告诉我所以我可以更新这个部分。我在 IE 中找到的最佳解决方案是附加到用户代理字符串或安装浏览器扩展以及您的应用程序,以公开 Javascript 可访问属性。
Firefox是迄今为止主要浏览器中最简单的,因为它允许您尝试捕获失败的导航尝试。返回的错误对象包含一个name
属性,其值为NS_ERROR_UNKNOWN_PROTOCOL
:
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
,所以 atry...catch
工作得很好。
Chrome官方在这方面很糟糕。如果自定义协议处理程序失败,它绝对会压缩。如果处理程序有效……您猜对了……它确实可以压缩。恐怕没有办法区分这两者。
我还没有测试过Safari,但我担心它会和 Chrome 一样。
欢迎您尝试我在调查时编写的测试代码(我自己对它有既得利益)。它与 Opera 和 Firefox 交叉兼容,但目前在 IE 和 Chrome 中没有任何作用。
为了配合我们自己的经验,我们使用 FireBreath 创建了一个简单的跨平台插件。安装后,此插件会注册一个 mime 类型,可以在页面刷新后从浏览器 javascript 中检测到该类型。检测到 MIME 类型表明已安装协议处理程序。
if(IE) { //This bastard always needs special treatment
try {
var flash = new ActiveXObject("Plugin.Name");
} catch (e) {
//not installed
}
else { //firefox,chrome,opera
navigator.plugins.refresh(true);
var mimeTypes = navigator.mimeTypes;
var mime = navigator.mimeTypes['application/x-plugin-name'];
if(mime) {
//installed
} else {
//not installed
}
}
这是一个现成的答案:在注册自定义协议时安装一种不寻常的字体。然后使用 javascript 来检查该字体是否存在,使用类似这样的东西。
当然这是一个黑客,但与其他答案不同,它可以跨浏览器和操作系统工作。
Windows 8 上的 Internet Explorer 10 引入了非常有用的navigator.msLaunchUri方法,用于启动自定义协议 URL 并检测成功或失败。例如:
if (typeof (navigator.msLaunchUri) == typeof (Function)) {
navigator.msLaunchUri(witchUrl,
function () { /* Success */ },
function () { /* Failure */ showError(); });
return;
}
Windows 7 / IE 9 及以下支持@mark-kahn 建议的条件注释。
对于 Internet Explorer,我发现的最佳解决方案是使用 Conditionl 注释和版本向量(应用程序在安装协议时必须向注册表写入一些内容,请参阅http://msdn.microsoft.com/en-us/library/ms537512.aspx #Version_Vectors )。protocolLong 不适用于自定义协议。