H5 打开 APP

三种方式

URL Scheme

语法:

[scheme]://[path][?query]
名称 作用
scheme 应用约定的协议名称,如微信是 weixin
path 需要访问的路径,由 app 定义
query 访问所携带的参数

Intent

该方法为安卓版本 Chrome 手机浏览器专用,由于绝大多数安卓默认浏览器是对 Chrome 浏览器的包装,所以该方式也需要关注。

语法:

intent://
[path]
#Intent;
  scheme=[scheme];
  package=[package];
  action=[action];
  category=[category];
  component=[component];
end;
名称 作用
path 路径信息
scheme 应用约定的协议名称,如微博是 weibo
package 应用的报名,如微博是 com.sina.weibo
action 传递给应用参数,表示该次跳转动作的名称
category 传递给应用参数,表示约束
component 传递给应用参数,表示目标类型

除了 schemepackage 必填外,其他字段可以不用填写。

例子

intent://qrcode#Intent;scheme=sinaweibo;package=com.sina.weibo;S.browser_fallback_url=http%3A%2F%2Fbaidu.com;end;

例子就是打开微博的扫二维码页面,可以不给 path 这个需要开发来确定,没有的话一般上是打开 app 这个同样需要安卓开发支持。

对比与 URL Scheme

优点:

  1. 可以通过设置 S.browser_fallback_url=[encoded_full_url] 确定当无法打开 app 时,需要跳转的链接。

缺点:

  1. Intent 形式的链接仅能在安卓浏览器上触发。

该形式为 ios 特有。

具体可以查看 UniversalLinks

需要 ios 开发者做一些特殊的配置,H5 方仅仅需要关注 ios 开发者给到的链接即可。该链接与正常链接一样,但一定是 https 开头。

打开媒介

前面说的 3 种形式最终都会生成一个字符串形式的链接。得到链接后,我们需要做的就是对这个链接发起一次请求即可。

具体的形式如下

  1. <a href="URL"> 直接作为 a 标签的 href,点击该标签即可跳转
  2. 通过监听点击事件,将 window.location.href = URL 即可实现跳转
  3. 通过监听点击事件,生成 iframe 并将 iframe.src = URL 即可实现跳转

但是不同的浏览器对这 3 种形式的唤起,以及链接的形式的支持各不相同,需要的注意点如下:

  1. URL Schemeios 9+ 上的浏览器中,只能通过 window.location 才能成功唤起 app
  2. URL Schemeandriod chrome 25+ 版本上必须手势触发,也就是通过 a 标签的点击触发,或是通过点击按钮后在使用 iframewindow.location.href
  3. Intent 需要 andriod chrome 25+ 并需要 app 支持。
  4. 实际测试下来,小米手机的默认浏览器使用 Intent 可以打开 app ,但是不能触发无应用时设置的跳转链接。
  5. Universal Link 需要 ios 9+ 并需要 app 支持。
  6. 微信、手Q、微博等内置的浏览器的环境下,以上 3 种形式都会有所限制,具体情况可以测试,不过基本上可以认为是失效的。

腾讯系 app

既然不能通过链接的形式打开 app 只能通过一些别的手段打开了。

  • ios 端,直接打开对应的 appstore 地址,打开后就能通过 appstore 打开对应的 app
  • andriod 端,打开对应的应用宝,同样的通过应用宝可以打开对应 app
  • 打开默认浏览器

但是,最上面两种处理方式只能打开 app 并不能打开 app 对应的页面,所以最好的处理方式仍是打开系统自带的默认浏览器,在通过浏览器打开 app

判断 app 是否打开成功

URL Scheme

对于 URL Scheme 由于浏览器只负责发送一次请求,而链接是否真正能打开 app 对于浏览器来说也并不知道,因此 URL Scheme 虽说通用,但是却有一个大缺陷,就是不能处理打开失败的情况。

因此我们只能用一些特殊的方法来处理打开失败的情况。由于打开了 app 那么浏览器就处在后台了,也就是隐藏了,可以通过浏览器页面是否处在隐藏状态下判断是否打开成功。

代码如下:

const initialTime = new Date();
let counter = 0;
let waitTime = 0;
const checkOpen = setInterval(() => {
    count++;
    waitTime = new Date() - initialTime;
    if (waitTime > 2500) {
        clearInterval(checkOpen);
    }
    if (counter < 100) return;
    const hide = document.hidden || document.webkitHidden;
    if (!hide) {
        cb(); // 唤端失败的回调函数
    }
}, 20);

这两个都可以设置打开失败的跳转链接,

  • IntentS.browser_fallback_url=[encoded_full_url]
  • Universal Link 可参考苹果官方文档,由于不需要前端关心,就不管了。

现有的库

callapp-lib

参考