我已经创建了一个自定义URL协议处理程序。
http://
mailto://
custom://
我已经注册了一个WinForms应用程序来做出相应的反应,一切都很好。
但是我希望在用户尚未安装自定义URL协议处理程序时能够优雅地处理这种情况。
为了能够做到这一点,我需要能够检测浏览器的已注册协议处理程序,我认为可以通过JavaScript来实现。但是我一直无法找到一种轮询信息的方法。我希望能够找到解决这个问题的方法。
感谢您可能能够分享的任何想法。
我已经创建了一个自定义URL协议处理程序。
http://
mailto://
custom://
我已经注册了一个WinForms应用程序来做出相应的反应,一切都很好。
但是我希望在用户尚未安装自定义URL协议处理程序时能够优雅地处理这种情况。
为了能够做到这一点,我需要能够检测浏览器的已注册协议处理程序,我认为可以通过JavaScript来实现。但是我一直无法找到一种轮询信息的方法。我希望能够找到解决这个问题的方法。
感谢您可能能够分享的任何想法。
这将是一种非常,非常“hacky”的方法来做到这一点...但是这样行得通吗?
远非万无一失...但可能有所帮助?
没有跨浏览器的好方法来做到这一点。在Win8+上的IE10+中,一个新的msLaunchUri
API使您能够启动一个协议,如下所示:
navigator.msLaunchUri('skype:123456',
function()
{
alert('success');
},
function()
{
alert('failed');
}
);
如果该协议未安装,则会触发失败回调函数。否则,协议将启动并触发成功回调函数。我在这里讨论了这个话题: https://web.archive.org/web/20180308105244/https://blogs.msdn.microsoft.com/ieinternals/2011/07/13/understanding-protocols/。目前似乎没有一种直接的JavaScript方法来检测已注册协议处理程序的安装情况。
在iTunes模型中,苹果提供了指向其服务器的URL,然后提供运行某些JavaScript代码的页面:
http://ax.itunes.apple.com/detection/itmsCheck.js
因此,iTunes安装程序显然会为主要浏览器部署插件,然后可以检测到这些插件的存在。
如果您的插件已安装,则可以比较确定地认为重定向到您的应用程序特定的URL将成功。
最简单的解决方法似乎是在用户第一次使用时询问用户。
例如,可以使用JavaScript确认对话框:
You need this software to be able to read this link. Did you install it ?
if yes: create a cookie to not ask next time; return false and the link applies
if false: window.location.href = '/downloadpage/'
在尝试打开自定义协议之前,向服务器脚本发出AJAX请求,将用户意图保存在数据库中(例如,保存用户ID和他想要执行的操作)。
尝试打开程序,并传递意图数据。
让程序请求服务器删除数据库条目(使用意图数据查找正确的行)。
使javascript轮询服务器一段时间,以查看数据库条目是否已删除。 如果该条目已被删除,则您将知道用户成功打开了应用程序,否则该条目将保留(您可以稍后使用cronjob将其删除)。
function launchCustomProtocol(elem, url, callback) {
var iframe, myWindow, success = false;
if (Browser.name === "Internet Explorer") {
myWindow = window.open('', '', 'width=0,height=0');
myWindow.document.write("<iframe src='" + url + "'></iframe>");
setTimeout(function () {
try {
myWindow.location.href;
success = true;
} catch (ex) {
console.log(ex);
}
if (success) {
myWindow.setTimeout('window.close()', 100);
} else {
myWindow.close();
}
callback(success);
}, 100);
} else if (Browser.name === "Firefox") {
try {
iframe = $("<iframe />");
iframe.css({"display": "none"});
iframe.appendTo("body");
iframe[0].contentWindow.location.href = url;
success = true;
} catch (ex) {
success = false;
}
iframe.remove();
callback(success);
} else if (Browser.name === "Chrome") {
elem.css({"outline": 0});
elem.attr("tabindex", "1");
elem.focus();
elem.blur(function () {
success = true;
callback(true); // true
});
location.href = url;
setTimeout(function () {
elem.off('blur');
elem.removeAttr("tabindex");
if (!success) {
callback(false); // false
}
}, 1000);
} else if (Browser.name === "Safari") {
if (myappinstalledflag) {
location.href = url;
success = true;
} else {
success = false;
}
callback(success);
}
}
实现Safari扩展很容易。它只包含一行注入脚本:
myinject.js:
window.postMessage("myappinstalled", window.location.origin);
接下来在网页JavaScript中,你需要首先注册消息事件,并在接收到消息时设置一个标志:
window.addEventListener('message', function (msg) {
if (msg.data === "myappinstalled") {
myappinstalledflag = true;
}
}, false);
myWindow.location.href;
和定义在该窗口内的iframe src
之间有什么联系?它是否应该抛出异常?无论自定义协议是否受支持,它都不会抛出异常。 - Burjuahttp://msdn.microsoft.com/en-us/library/ms537503%28VS.85%29.aspx#related_topics
"If you have some control over the binaries being installed on a user's machine, checking the UA in script seems like a relevant approach: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\5.0\User Agent\Post Platform " -- By M$ support我正在尝试做类似的事情,我刚刚发现了一个在Firefox中有效的技巧。如果你将它与IE的技巧结合起来,你就可以拥有一个在两个主要浏览器上都能运行的技巧(我不确定它是否适用于Safari,我知道它在Chrome中不起作用)
if (navigator.appName=="Microsoft Internet Explorer" && document.getElementById("testprotocollink").protocolLong=="Unknown Protocol") {
alert("No handler registered");
} else {
try {
window.location = "custom://stuff";
} catch(err) {
if (err.toString().search("NS_ERROR_UNKNOWN_PROTOCOL") != -1) {
alert("No handler registered");
}
}
}
<a id="testprotocollink" href="custom://testprotocol" style="display: none;">testprotocollink</a>
这个方法有点取巧,但它确实有效。不幸的是,Firefox 版本仍会弹出默认警报,当您尝试访问一个未知协议的链接时,但在警报被解除后,它将运行您的代码。
function OpenCustomLink(link) {
var w = window.open(link, 'xyz', 'status=0,toolbar=0,menubar=0,height=0,width=0,top=-10,left=-10');
if(w == null) {
//Work Fine
}
else {
w.close();
if (confirm('You Need a Custom Program. Do you want to install?')) {
window.location = 'SetupCustomProtocol.exe'; //URL for installer
}
}
}