javascript - 启动应用程序(如果已安装)或重定向以下载

标签 javascript macos github href url-scheme

在每个 repo 上,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 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"}

如果您正在运行 GitHub Conduit 服务,页面上的 JavaScript 会从此 URL 获取数据,并为“桌面克隆”按钮提供 github-mac:// URL。否则,该 URL 将返回 404 响应,并假定您没有安装 GitHub for Mac,并为您提供下载链接。


如何实现这样的功能?

不幸的是,浏览器中没有 JavaScript API 可以执行此操作。浏览器无法识别的协议(protocol)由操作系统本身处理。我尽了最大努力,但我只能为 Mac 上的 Firefox 破解出一个像样的纯 JavaScript 解决方案,并为 Safari 破解出一个丑陋的半生不熟的解决方案。这两种 hack 都依赖于未定义的行为,并且都不适用于 Chrome。你可以在下面看到我的研究代码。

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

执行此操作的 JavaScript 代码相当简单。假设您返回适当的 CORS header ,您可以只发出一个简单的 AJAX 请求。这是一个基于 jQuery 的示例。

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


研究代码:

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

火狐:

此代码依赖于在 iframe 中打开链接,当无法识别协议(protocol)时会触发错误(成功后它将正常打开 URL)。

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);
}

示例用法:

//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 :

此代码依赖于在新选项卡中打开 URL,如果 URL没有被认出。如果不幸无法打开协议(protocol),“没有设置为打开 URL 的应用程序”对话框仍会打开。

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);
}

示例用法:

//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!');
    });
});

关于javascript - 启动应用程序(如果已安装)或重定向以下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28389679/

相关文章:

python - 为什么这个简单的 Tkinter 教程脚本在 Raspberry Pi 上运行良好,但在 MacOS 上却不行?

git - 是否可以在 Github 和 Gitlab 上放置一个 Git 存储库?

调用函数的 Javascript 顺序

objective-c - NSPopover 的 contentViewController 中的动画变化

javascript - 使用 Javascript,如何在点击 anchor 标记后为元素的移动设置动画?

macos - 无法打开显示错误

github - 使 github 中的 jira 链接可点击

github - 如何将 GitHub 字体切换为以前的样式?

javascript - module.exports 客户端

javascript - DOMParser.parseFromString 失败并显示 XML5619 : Incorrect document syntax