我创建了一个自定义URL协议处理程序。
http://
mailto://
custom://
我已经注册了WinForms应用程序来做出相应的响应。这一切都很好。
但是我希望能够优雅地处理用户尚未安装自定义URL协议处理程序的情况。
为了能够做到这一点,我需要能够检测到浏览器的注册协议处理程序,我假设使用JavaScript。但是我一直无法找到一种方法来查询信息。我希望找到解决这个问题的方法。
感谢您提出的任何想法。
我创建了一个自定义URL协议处理程序。
http://
mailto://
custom://
我已经注册了WinForms应用程序来做出相应的响应。这一切都很好。
但是我希望能够优雅地处理用户尚未安装自定义URL协议处理程序的情况。
为了能够做到这一点,我需要能够检测到浏览器的注册协议处理程序,我假设使用JavaScript。但是我一直无法找到一种方法来查询信息。我希望找到解决这个问题的方法。
感谢您提出的任何想法。
Answers:
这将是一个非常,非常 哈克做到这样......但将这项工作?
远非防弹...但可能有所帮助?
没有很好的跨浏览器方法来做到这一点。在Win8 +的IE10 +中,msLaunchUri
api使您可以启动协议,如下所示:
navigator.msLaunchUri('skype:123456',
function()
{
alert('success');
},
function()
{
alert('failed');
}
);
如果未安装协议,则将触发故障回调。否则,协议将启动,并且成功回调将触发。
我在这里进一步讨论了这个主题:http : //blogs.msdn.com/b/ieinternals/archive/2011/07/14/url-protocols-application-protocols-and-asynchronous-pluggable-protocols-oh-my .aspx
HTML5定义了自定义方案和内容处理程序(据我所知,Firefox是迄今为止唯一的实现程序),但是不幸的是,目前尚无办法检查处理程序是否已存在-已提出该处理程序,但没有后续措施。这似乎是有效使用自定义处理程序的一项关键功能,我们开发人员应注意此问题,以使其实现。
似乎没有直接的方法可以通过javascript来检测是否存在已注册协议处理程序的已安装应用。
在iTunes模型中,Apple向其服务器提供url,然后这些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/'
我能够最终得到一个跨浏览器(浏览器32,火狐27,IE 11,Safari浏览器6)溶液用工作的组合这和超简单的Safari扩展。在这个问题和另一个问题中,已经以一种或另一种方式提到了许多这种解决方案。
这是脚本:
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);
假定与自定义协议关联的应用程序将管理Safari扩展的安装。
在所有情况下,如果回调返回false,您将通知用户未安装该应用程序(即,它的自定义协议)。
myWindow.location.href;
与src
该窗口中定义的iframe之间的连接是什么?它应该引发异常吗?不管是否支持自定义协议,都不会。
您说您需要检测浏览器的协议处理程序-真的吗?
如果您做了类似从Sourceforge下载文件时发生的事情该怎么办?假设您要打开myapp:// something。与其简单地创建一个链接,不如创建到另一个通过HTTP访问的HTML页面的链接。然后,在该页面上,说您正在尝试为他们打开应用程序。如果不起作用,他们需要安装您的应用程序,可以通过单击您提供的链接来完成。如果它确实有效,那么您就一切准备就绪。
您可以尝试如下操作:
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
}
}
}
我正在尝试做类似的事情,但我发现了一个可与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>
这有点hacky,但是可以用。不幸的是,当您尝试访问具有未知协议的链接时,Firefox版本仍会弹出默认警报,但是该警报将在警报消失后运行。
这是Microsoft支持的IE建议的方法
http://msdn.microsoft.com/zh-cn/library/ms537503%28VS.85%29.aspx#related_topics
“如果对用户计算机上安装的二进制文件有一定的控制权,则检查脚本中的UA似乎是一种相关方法:HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Internet Settings \ 5.0 \ User Agent \ Post Platform”-由M $支持
每个网页都可以访问userAgent字符串,如果您删除自定义的发布平台值,则使用navigator.userAgent在javascript中进行检测非常简单。
幸运的是,当单击带有自定义协议的链接并且用户计算机上未安装该协议时,其他主要浏览器(如Firefox和Chrome)(除非Safari :(),不会引发“找不到页面”)错误。 ,任何在看不见的框架中单击或捕获javascript错误的技巧均不起作用,最终以丑陋的“无法显示网页”错误告终。我们在本例中使用的技巧是告知具有浏览器特定图像的用户单击自定义协议链接将打开一个应用程序,如果他们没有找到打开的应用程序,则可以单击“安装”页面。就XD而言,这种wprks方式比IE的ActiveX方法要好。对于FF和Chrome,请继续并在没有任何检测的情况下启动自定义协议。让用户告诉您所看到的内容。对于Safari ,:(尚无答案