最近遇到一个需求,需要在从APP分享出去的H5页面中,带有一个立即打开的按钮,如果本地安装了app,那么就直接唤起本地的app,如果没有安装,则跳转到下载。这是一个很正常的推广和导流量的策略。前端小白从来没有做过这个需求,只能开始哼唧哼唧地开启自己的度娘和谷歌之旅。

经过一段时间的探索之旅发现里面的学问很多,要做一个兼容性很好的方案,就需要考虑各种情况,在不同的情况适配不同的方案,比方说用户是在手机浏览器打开还是微信中打开,或者是在pc中打开,universal腾讯应用宝直接打开 APP link是否被关闭等,这就使代码实现变得复杂,且容易出错,且还有安卓平台机型众多、浏览器众多等导致的兼容问题。由于时间有限,这次主要先介绍一个比较普遍的使用URL Scheme进行App跳转的方法。

URL Scheme —— 唤端媒介

来源

一般来说,我们使用的智能设备上有许多我们的个人信息。比如:联系方式、银行卡/信用卡信息、支付宝/Paypal/各大商城的账户密码、照片甚至行程与位置信息等。

如果说,你设备上的每一个应用,不管是官方的还是你从任何商城安装的应用都可以随意地获取这些信息,那么你轻则收到骚扰信息和邮件、重则后果不堪设想。如何让这些信息不被其它应用随意使用,或者说,如何让这些信息仅在设备所有者本人知情并允许的情况下被使用,是所有智能设备与操作系统所要在乎的核心安全问题。针对这个问题,苹果使用了名为「沙盒」的机制:应用只能访问它声明可能访问的资源。一切提交到 App Store 的应用都必须遵守这个机制。

在安全方面沙盒是个很好的解决办法,但是有些矫枉过正。敏感的个人信息我们不愿意透露,却不代表所有的信息我们都不想与其它应用共享。因此,我们急需要一个辅助工具来帮助我们实现应用通信, URL Schemes 就是这个工具。

URL Schemes是什么

[scheme]://[host]/[path]?[query]

我们拿 https://www.baidu.com 来举例,scheme 自然就是 https 了,后面拼接的是传递的参数。URL Schemes 没有特别严格的规范,所以后面参数的具体定义是app开发者去自定义。

就像给服务器资源分配一个 URL,以便我们去访问它一样,我们同样也可以给手机APP分配一个特殊格式的 URL,用来访问这个APP或者这个APP中的某个功能(来实现通信)。APP得有一个标识,好让我们可以定位到它,它就是 URL 的 Scheme 部分。

但是,两者还有几个重要的区别:

  • 所有网页都一定有网址,不管是首页还是子页。但未必所有的应用都有自己的 URL Schemes,更不是每个应用的每个功能都有相应的 URL Schemes。几乎没有所有功能都有对应 URL 的应用。一个 App 是否支持 URL Schemes 要看那个 App 的作者是否在自己的作品里添加了 URL Schemes 相关的代码。
  • 一个网址只对应一个网页,但并非每个 URL Schemes 都只对应一款应用。这点是因为苹果没有对 URL Schemes 有不允许重复的硬性要求,所以曾经出现过有 App 使用支付宝的 URL Schemes 拦截支付帐号和密码的事件。
  •  一般网页的 URL 比较好预测,而URL Scheme 因为没有统一标准,所以非常难猜,通过猜来获取 应用的 URL Schemes 是不现实的。

前面普及了一下URL Schemes的相关知识,作为个前端开发者,就不去深究其中的原理,都交给app开发者吧。接下来开始我们的正题。首先当然是要客户端提供App的Url Schemes。

用浏览器去打开scheme

在浏览器中打开 scheme 就像打开一个不同的http地址一样。可以在一个 a 标签中打开。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>打开App</title>
</head>
<body>
<a href="luwei://" id="open">打开应用</a>
</body>
</html>

点击上面的H5页面中的链接将会尝试唤醒对应app,在一些浏览器中,可能会弹出一个提示框,询问用户是否允许打开应用。

如果打开的 scheme 在本地没有对应的 app,则点击不会反应。

当然还可以使用 JavaScript 代码打开,只需要添加相应的事件触发和处理即可。

在JavaScript代码中打开连接有以下几种方式:

  • 新建一个隐藏的 iframe ,地址指向需要打开的url
  • 使用 window.location 或者 window.location.href 刷新当前页面
  • 新建一个隐藏的 a 标签,地址指向打开的url,并触发打开链接事件
  • 动态创建一个script脚本,在这个脚本中新建一个a标签并打开
// 打开url的方式
var urlOpen = {
  // 在ios支持不好
    'iframe' : function(url) {
        var iframe = document.createElement('iframe');
        iframe.style.display = 'none';
        iframe.src = url;
        document.body.appendChild(iframe);
    },
    'location' : function(url) {
        window.location.href = url;
    },
    'href' : function(url) {
        var a = document.createElement('a');
        a.style.display = 'none';
        a.href = url;
        document.body.appendChild(a);
        a.click();
    },
    'script' : function(url) {
        var script = document.createElement('script');
        script.setAttribute('type', 'test/javascript');
        script.innerHTML = '(function(){'  
            'var a = document.createElement("a");'  
            'a.style.display = "none";'  
            'a.href = "'   url.replace(/"/g, '\\"')   '";'  
            'document.body.appendChild(a);'  
            'a.click();'  
            '})()';
        document.body.appendChild(script);
    },
    'open' : function(url) {
        window.open(url);
    }
};

以上方法是只是解决了在已安装App设备唤醒App的功能,并不能判断是否已安装App,没有安装即跳转至下载链接。

浏览器判断是否安装应用

在浏览器实际上是没有能力判断手机里是否安装了某个App的,所以只能够采取一种投机取巧的方式。

在JavaScript中判断页面是否进入后台来判断打开成功。Html5提供了下列事件和属性可以利用:

  • pagehide : 页面隐藏时触发
  • visibilitychange : 页面隐藏没有在当前显示时触发(切换tab也会触发该事件)
  • document.hidden : 当页面隐藏时,该值为true,显示时为false

上面这些事件或者属性并不是所有浏览器都支持。下面是一个给出为id为openBtn 的按钮添加打开scheme或者下载事件的例子,但对于Android 4.4版本以下则不支持

    var downloader, 
    scheme = 'luwei://',  // 需要打开的app scheme 地址
    iosDownload='http://xxx.com';  // 如果打开scheme失效的app下载地址
    andDownload = 'http://xxx.com';
    var u = navigator.userAgent;
    var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //g
    var isIOS = !!u.match(/\(i[^;] ;( U;)? CPU. Mac OS X/); //ios终端

// 给 id 为 openBtn 的按钮添加点击事件处理函数
    document.getElementById('openBtn').onclick = function () {
        window.location.href = scheme;  // 尝试打开 scheme 
 
        // 设置3秒的定时下载任务,3秒之后下载app
        downloader = setTimeout(function(){
            if(isAndroid) {
                window.location.href = andDownload;
            }
            if(isIOS) {
                window.location.href = iosDownload;
            }
          
        }, 3000);
    };
 
    document.addEventListener('visibilitychange webkitvisibilitychange', function () {
        // 如果页面隐藏,推测打开scheme成功,清除下载任务
        if (document.hidden || document.webkitHidden) {
            clearTimeout(downloader);
        }
    });
    window.addEventListener('pagehide', function() {
        clearTimeout(downloader);
    });

没有完美的方案

微信中无法唤醒App,需要“用浏览器打开”是因为微信对所有的分享链接接做了scheme屏蔽,也就是说分享连接中所有对于scheme的调用都被微信封掉了。有些app是能在微信打开是因为微信有一个白名单(有关系就是不错),对于在白名单中的分享链接是不会屏蔽掉scheme调用的。
本文只是小小地抛个砖,介绍了一种比较常用简单的方法去唤醒app,该方案兼容性不是特别好吧。要做出一个比较完美的方案还需要细细去钻研,还需要不停地去搬砖~不说了,搬砖去了~

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持Devmax。

html5唤醒APP小记的更多相关文章

  1. 使用HTML5做的导航条详细步骤

    这篇文章主要介绍了用HTML5做的导航条详细步骤,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  2. 详解HTML5中的picture元素响应式处理图片

    这篇文章主要介绍了详解HTML5中的picture元素响应式处理图片,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  3. html5利用canvas实现颜色容差抠图功能

    这篇文章主要介绍了html5利用canvas实现颜色容差抠图功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  4. HTML5拖拽功能实现的拼图游戏

    本文通过实例代码给大家介绍了HTML5拖拽功能实现的拼图游戏,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧

  5. HTML5实现直播间评论滚动效果的代码

    这篇文章主要介绍了HTML5实现直播间评论滚动效果的代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. 使用Html5多媒体实现微信语音功能

    这篇文章主要介绍了使用Html5多媒体实现微信语音功能,需要的朋友可以参考下

  7. HTML5 播放 RTSP 视频的实例代码

    目前大多数网络摄像头都是通过 RTSP 协议传输视频流的,但是 HTML 并不标准支持 RTSP 流。本文重点给大家介绍HTML5 播放 RTSP 视频的实例代码,需要的朋友参考下吧

  8. html5 拖拽及用 js 实现拖拽功能的示例代码

    这篇文章主要介绍了html5 拖拽及用 js 实现拖拽,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. HTML5自定义视频播放器源码

    这篇文章主要介绍了HTML5自定义视频播放器源码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  10. HTML5新增form控件和表单属性实例代码详解

    这篇文章主要介绍了HTML5新增form控件和表单属性实例代码详解,需要的朋友可以参考下

随机推荐

  1. 微信小程序canvas实现水平、垂直居中效果

    这篇文章主要介绍了小程序中canvas实现水平、垂直居中效果,本文图文实例代码相结合给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

  2. 使用HTML5做的导航条详细步骤

    这篇文章主要介绍了用HTML5做的导航条详细步骤,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  3. H5最强接口之canvas实现动态图形功能

    这篇文章主要介绍了H5最强接口之canvas实现动态图形功能,需要的朋友可以参考下

  4. Canvas高级路径操作之拖拽对象的实现

    这篇文章主要介绍了Canvas高级路径操作之拖拽对象的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  5. html5视频自动横过来自适应页面且点击播放功能的实现

    这篇文章主要介绍了h5视频自动横过来自适应页面且点击播放,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. 详解HTML5中的picture元素响应式处理图片

    这篇文章主要介绍了详解HTML5中的picture元素响应式处理图片,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. canvas像素点操作之视频绿幕抠图

    这篇文章主要介绍了canvas像素点操作之视频绿幕抠图的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  8. html5利用canvas实现颜色容差抠图功能

    这篇文章主要介绍了html5利用canvas实现颜色容差抠图功能,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

  9. canvas绘制视频封面的方法

    这篇文章主要介绍了canvas绘制视频封面的方法的相关资料,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  10. HTML5拖拽功能实现的拼图游戏

    本文通过实例代码给大家介绍了HTML5拖拽功能实现的拼图游戏,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧

返回
顶部