启动应用程序,如果已安装或重定向下载 [英] Launch app if installed or redirect to download

查看:167
本文介绍了启动应用程序,如果已安装或重定向下载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在每个回购协议中,GitHub都有一个标签为桌面克隆的按钮(例如: https ://github.com/github/developer.github.com )。如果你安装了GitHub for Mac,那么 href 就像是:

  github-mac:// openRepo / https://github.com/github/developer.github.com 

这将打开GitHub for Mac并提供克隆回购。如果你不这样做,那么 href 是:

  http:/ / mac.github.io` 

这是GitHub for Mac的下载页面。我想在我的网站上做类似的事情:如果已安装,请打开我的应用程序,如果没有,请重新下载。如何才能做到最好?

解决方案

GitHub如何做到这一点?



GitHub for Mac 客户端包含名为 GitHub Conduit 在后台运行。 GitHub页面通过URL https://ghconduit.com:25035/status 与此服务进行通信。



摘自 GitHub管道帮助页面




例如,Conduit位于存储库页面 Clone in Desktop 按钮的后面,打开按钮在文件页面上。 Conduit监听来自浏览器的关于GitHub for Mac操作的查询。要查看这一行动,请访问 https://ghconduit.com:25035/status 。它应该看起来像这样:




  {capabilities:[status, unique_id,url-parameter-filepath],running:true,server_version:5} 

如果您运行的是GitHub Conduit服务,则页面上的JavaScript从此URL中提取数据并为桌面上的Clone按钮设置一个 github-mac:// URL。否则,该URL会返回一个404响应,并且假定您没有安装GitHub for Mac,并为您提供链接以下载它。




p>

如何实现这样的功能?



不幸的是,在浏览器中没有JavaScript API来执行此操作。浏览器无法识别的协议由操作系统本身处理。我尽了最大的努力,但我只能在Mac上为Firefox提供一个体面的仅限于JavaScript的解决方案,并为Safari提供了一个丑陋的一半解决方案。这两种攻击都取决于未定义的行为,并且都不适用于Chrome。您可以在下面看到我的研究代码。



如果您想要使用GitHub方式,您必须创建一个本地HTTP服务器,该服务器作为已知服务运行您的用户机器上的端口。然后,您可以使用JavaScript连接它并检索有关已安装应用程序的信息。这样做并不是微不足道的,除非它提供了一些惊人的功能,否则我会建议不要这样做。



尽管如此,JavaScript代码很简单。假设你返回适当的CORS头文件,你可以做一个简单的AJAX请求。这是一个基于jQuery的示例。

  $。ajax({
url:'http://127.0.0.1 :1337',
dataType:'json',
成功:函数(jqXHR){
//将链接替换为应用协议网址
}
});




研究代码:



下面的代码是我对Firefox和Safari的超级hacky和相当脆弱的代码。虽然它正在为我的目标而努力,但我绝对不能保证它能够按预期工作,或将来继续工作。它依赖于浏览器特定的未定义行为,应该被认为是不稳定的。我也不知道这段代码在非OS X系统上会做什么。



Firefox:



代码依赖于在iframe中打开链接,当协议无法识别时会触发错误(成功时它会像平常一样打开URL)。

  function openAppFirefox(url,failure){
var iframe = document.createElement('iframe');
//如果协议无法打开,Firefox将触发错误。
iframe.onerror = function(){
failure();
};
//隐藏iframe。
iframe.style.width = 0;
iframe.style.height = 0;
iframe.style.visibility =hidden;
iframe.style.position =fixed;
//载入网址。
iframe.src = url;
document.body.appendChild(iframe);
//清理iframe。
setTimeout(function(){
document.body.removeChild(iframe);
},1000);





用法示例:



  //将工作。 
// var url ='itmss://itunes.apple.com/us/app/stack-exchange/id871299723';
//将失败。
var url ='wat:// bummer';
someElment.addEventListener('click',function(){
openAppFirefox(url,function(){
alert('Download my app!');
});
});






Safari:



这段代码依靠在一个新标签中打开URL,它的 win.location.href 会在 undefined c>。不幸的是,如果打开协议失败,没有应用程序设置为打开URL对话框仍然会打开。

 函数openAppSafari(url,失败){
var win = window.open(url);
var done = function(failed){
win.close();
clearInterval(checkFail);
clearTimeout(giveup);
if(failed){
failure();
}
};
// Chck失败。
var checkFail = setInterval(function(){
//在Safari中,location.href在失败时变为undefined。
if(!win.location.href){
done true);
}
});
//一秒钟后,假设成功。
var giveup = setTimeout(function(){
done(false);
},1000);





用法示例:



  //将工作。 
// var url ='itmss://itunes.apple.com/us/app/stack-exchange/id871299723';
//将失败。
var url ='wat:// bummer';
someElment.addEventListener('click',function(){
openAppSafari(url,function(){
alert('Download my app!');
});
});


On every repo, GitHub has a button that is labelled "Clone in Desktop" (example: https://github.com/github/developer.github.com). If you have GitHub for Mac installed, the href is something like:

github-mac://openRepo/https://github.com/github/developer.github.com

This opens GitHub for Mac and offers to clone the repo. If you don't, the href is:

http://mac.github.io`

This is a download page for GitHub for Mac. I would like to do something similar on my website: open my app if installed and redirect to download if not. How can this be best accomplished?

解决方案

How does GitHub do it?

The GitHub for Mac client includes a local service called GitHub Conduit that runs in the background. The GitHub page communicates with this service through the the URL https://ghconduit.com:25035/status.

Excerpt from the GitHub Conduit help page:

For example, Conduit is behind the Clone in Desktop button on repository pages and the Open button on file pages. Conduit listens for queries from the browser about GitHub for Mac actions. To see this in action, visit https://ghconduit.com:25035/status. It should look something like this:

{"capabilities":["status","unique_id","url-parameter-filepath"],"running":true,"server_version":"5"}

If you have the GitHub Conduit service running, JavaScript on the page fetches data from this URL and give the Clone in Desktop button a github-mac:// URL. Otherwise, the URL returns a 404 response and it assumes you do not have GitHub for Mac installed, and gives you the link to download it.


How to implement functionality like this?

Unfortunately, there is no JavaScript API to do this in the browser. Protocols the browser does not recognize are handled by the OS itself. I tried my best, but I was only able to hack-up a decent JavaScript-only solution for Firefox on Mac, and an ugly half-baked solution for Safari. Both hacks hinge on undefined behavior, and neither work for Chrome. You can see my research code below.

If you want to do it the GitHub way, you will have to create a local HTTP server that runs as a service over a known port on your user's machines. Then you can use JavaScript to connect to it and retrieve information about the installed application. Doing this would not be trivial, and unless it provides some amazing functionality, I would advise against doing this.

The JavaScript code to do this would be fairly simple though. Assuming you return the appropriate CORS headers, you could just make a simple AJAX request. Here's a jQuery-based example.

$.ajax({
    url: 'http://127.0.0.1:1337',
    dataType: 'json',
    success: function(jqXHR) {
        //Replace links to app protocol URLs.
    }
});


Research Code:

The following code is my super-hacky and rather fragile code for Firefox and Safari. While it is working on my end, I make absolutely no guarantee that it will work as expected, or will continue to work in the future. It relies on browser-specific undefined behavior, and should be considered unstable. I also have no idea what this code will do on non-OS X systems.

Firefox:

This code relies on opening the link in an iframe that will trigger an error when a protocol is unrecognized (on success it will open the URL as normal).

function openAppFirefox(url, failure) {
    var iframe = document.createElement('iframe');
    //Firefox will fire an error if protocol fails to open.
    iframe.onerror = function() {
        failure();
    };
    //Hide the iframe.
    iframe.style.width = 0;
    iframe.style.height = 0;
    iframe.style.visibility = "hidden";
    iframe.style.position = "fixed";
    //Load the URL.
    iframe.src = url;
    document.body.appendChild(iframe);
    //Clean up the iframe.
    setTimeout(function() {
        document.body.removeChild(iframe);
    }, 1000);
}

Example Usage:

//Will work.
//var url = 'itmss://itunes.apple.com/us/app/stack-exchange/id871299723';
//Will fail.
var url = 'wat://bummer';
someElment.addEventListener('click', function() {
    openAppFirefox(url, function() {
        alert('Download my app!');
    });
});


Safari:

This code relies on opening the URL in a new tab, whose win.location.href will before undefined within a second (but probably less time) if the URL was not recognized. The "There is no application set to open the URL" dialog will still open if it fails to open the protocol unfortunately.

function openAppSafari(url, failure) {
    var win = window.open(url);
        var done = function(failed) {
            win.close();
            clearInterval(checkFail);
            clearTimeout(giveup);
            if (failed) {
                failure();
            }
        };
        //Chck for failure.
        var checkFail = setInterval(function() {
        //In Safari, location.href becomes undefined on failure.
        if (!win.location.href) {
            done(true);
        }
    });
    //After a second, assume success.
    var giveup = setTimeout(function() {
        done(false);
    }, 1000);
}

Example Usage:

//Will work.
//var url = 'itmss://itunes.apple.com/us/app/stack-exchange/id871299723';
//Will fail.
var url = 'wat://bummer';
someElment.addEventListener('click', function() {
    openAppSafari(url, function() {
        alert('Download my app!');
    });
});

这篇关于启动应用程序,如果已安装或重定向下载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆