在做 h5 页面中,会遇到这样一个需求,有一个立即打开的按钮,如果本地安装了我们的 app,那么点击就直接唤起本地 app,如果没有安装,则跳转到下载。

  首先想到的是两个问题:一是如何唤起本地 app,二是如何判断浏览器是否安装了对应 app。

  如何唤起本地 app

  首先,想要实现这个需求,肯定是必须要客户端同学的配合才行,因此我们不用知道所有的实现细节,我们从前端角度思考看这个问题,需要知道的一点是,ios 与 Android 都支持一种叫做 schema 协议的链接。比如网易新闻客户端的协议为

  JavaScript

  1. newsapp://xxxxx

  当然,这个协议不需要我们前端去实现,我们只需要将协议放在 a 标签的 href 属性里,或者使用 location.href 与 iframe 来实现激活这个链接。而 location.href 与 iframe 是解决这个需求的关键。

  在 ios 中,还支持通过smart app banner来唤起 app,即通过一个 meta 标签,在标签里带上 app 的信息,和打开后的行为,代码形如

  XHTML

  1. <meta name="apple-itunes-app" content="app-id=1023600494, app-argument=tigerbrokersusstock://com.tigerbrokers.usstock/post?postId=7125" />

  需要注意的是:我们就没办法通过这个协议在微信中直接唤起 app。原因是微信里屏蔽了 schema 协议,除非你是微信的合作伙伴之类的,他们专门给你配置进白名单。

  因此我们会判断页面场景是否在微信中,如果在微信中,则会提示用户在浏览器中打开。

  如何判断本地是否安装了 app

  首先我们可以确认的是,在浏览器中无法明确的判断本地是否安装了 app。因此我们必须采取一些取巧的思路来解决这个问题。

  我们能够很容易想到,采用设置一个延迟定时器 setTimeout 的方式,第一时间尝试唤起 app,如果 200ms 没有唤起成功,则默认本地没有安装 app,200ms 以后,将会触发下载行为。

  结合这个思路,我们来全局考虑一下这个需求应该采用什么样的方案来实现它。

  使用 location.href 的同学可能会面临一个担忧,在有的浏览器中,当我们尝试激活 schema link 的时候,若本地没有安装 app,则会跳转到一个浏览器默认的错误页面去了。因此大多数人采用的解决方案都是使用 iframe

  测试了很多浏览器,没有发现过这种情况

  后来观察了网易新闻,今日头条,YY 等的实现方案,发现大家都采用的是 iframe 来实现。好吧,面对这种情况,只能屈服。

  整理一下目前的思路,得到下面的解决方案

 

  想法很美好,现实很残酷。一测试,就发现简单的这样实现有许多的问题。

  第一个问题在于,当页面成功唤起 app 之后,我们再切换回来浏览器,发现跳转到了下载页面。

  为了解决这个问题,发现各个公司都进行了不同方式的尝试。

  也是历经的很多折磨,发现了几个比较有用的事件。

  pageshow 页面显示时触发,在 load 事件之后触发。需要将该事件绑定到 window 上才会触发

  pagehide 页面隐藏时触发

  visibilitychange 页面隐藏没有在当前显示时触发,比如切换 tab,也会触发该事件

  document.hidden 当页面隐藏时,该值为 true,显示时为 false

  由于各个浏览器的支持情况不同,我们需要将这些事件都给绑定上,即使这样,也不一定能够保证所有的浏览器都能够解决掉这个小问题,实在没办法的事情就不管了。

  因此需要扩充一下上面的方案,当本地 app 被唤起,则页面会隐藏掉,就会触发 pagehide 与 visibilitychange 事件

  而另外一个问题就是 IOS9+ 下面的问题了。ios9 的 Safari,根本不支持通过 iframe 跳转到其他页面去。也就是说,在 safari 下,我的整体方案被全盘否决!

  于是我就只能尝试使用 location.href 的方式,这个方式能够唤起 app,但是有一个坑爹的问题,使用 schema 协议唤起 app 会有弹窗而不会直接跳转去 app!甚至当本地没有 app 时,会被判断为链接无效,然后还有一个弹窗。

  这个弹窗会造成什么问题呢?如果用户不点确认按钮,根据上面的逻辑,这个时候就会发现页面会自动跳转到下载去了。而且无效的弹窗提示在用户体验上是不允许出现的。

  好吧,继续扒别人的代码,看看别人是如何实现的。然后我又去观摩了其他公司的实现结果,发现网易新闻,今日头条都可以在 ios 直接从微信中唤起 app。真是神奇了,可是今日头条在 Android 版微信上也没办法直接唤起的,他们在 Android 上都是直接到腾讯应用宝的下载里去。所以按道理来说这不是添加了白名单。

  为了找到这个问题的解决方案,我在网易新闻的页面中扒出了他们的代码,并整理如下,添加了部分注释(因涉及的代码块篇幅过长,考虑到阅读效果,请至阅读原文查看。

  虽然有一些外部的引用,和一些搞不懂是干什么用的方法和变量,但是基本逻辑还是能够看明白。好像也没有什么特别的地方。研究了许久,看到了一个 jsonp 请求很奇特。这是来干嘛用的?

  于是费尽千辛万苦,搜索了很多文章,最终锁定了一个关键的名词 Universal links。

  如果我早知道这个名词,那么问题就不会变的那么束手无策。所以这个东西是什么呢?

  Apple 为 iOS 9 发布了一个所谓的通用链接的深层链接特性,即 Universal links。虽然它并不完美,但是这一发布,让数以千计的应用开发人员突然意识到自己的应用体验被打破。

  Universal links,一种能够方便的通过传统的 HTTP/HTTPS 链接来启动 App,使用相同的网址打开网站和 App。

  关于这个问题的提问与 universal links 的介绍请至阅读原文

  ios9 推行的一个新的协议!

  关于本文的这个问题,国内的论坛有许许多多的文章来解决,但是提到 universal links 的文章少之又少,而我想吐槽的是,我们的 ios 开发也尼玛不知道这个名词,搞什么鬼。他改变了用户体验的关键在于,微信没有屏蔽这个协议。因此如果我们的 app 注册了这个协议,那么我们就能够从微信中直接唤起 app。

  这个时候我就发现,上面贴的网易新闻代码中的 jsonp 请求的内容,就是这个协议必须的一个叫做apple-app-site-association的 JSON 文件

  大家可以直接访问这个链接,查看里面的内容

  http://active.163.com/service/form/v1/5847/view/1047.jsonp

  至于 universal links 具体如何实现,让 ios 的同学去搞定吧,这里提供两个参考文章

  http://www.cocoachina.com/bbs/read.php?tid-1486368.html

  https://blog.branch.io/how-to-setup-universal-links-to-deep-link-on-apple-ios-9

  支持了这个协议之后,我们又可以通过 iframe 来唤起 app 了,因此基本逻辑就是这样了。最终的调研结果是

  没有完美的解决方案

  就算是网易新闻,这个按钮在使用过程中也会有一些小 bug,无法做到完美的状态。

  因为我们面临许多没办法解决的问题,比如无法真正意义上的判断本地是否安装了 app,pageshow,pagehide 并不是所有的浏览器都支持等。很多其他博客里面,什么计算时间差等方案,根!本!没!有!用!我还花了很久的时间去研究这个方案。

  老实说,从微信中跳转到外部浏览器,并不是一个好的解决方案,这样会导致很多用户流失,因此大家都在 ios 上实现了 universal links,而我更加倾向的方案是知乎的解决,他们从设计上避免了在一个按钮上来判断这个逻辑,而采用了两个按钮的方式。

  网易新闻的逻辑是,点击打开会调整到一个下载页面,这个下载页面一加载完成就尝试打开app,如果打开了就直接跑到 app 里面去了,如果没有就在页面上有一个立即下载的按钮,按钮行只有下载处理。

浏览器唤起APP的思路(本文转载)的更多相关文章

  1. 浏览器唤起APP的功能

    http://blog.html5funny.com/2015/06/19/open-app-from-mobile-web-browser-or-webview/ http://panli.mu.g ...

  2. 【js】手机浏览器端唤起app,没有app就去下载app 的方法

    这种功能的作用: 1.一般公司有自己的app,而app是需要不断有新用户涌入才能持续运营,达到不错的收入.就需要使用这种方式进行引入新的用户. 2.一些内容在网页端体验不好,或者一些功能需要app内才 ...

  3. h5页面唤起app(iOS和Android),没有安装则跳转下载页面

    浏览器和app没有通信协议,所以h5不知道用户的手机释放安装了app.因此只能是h5去尝试唤起app,若不能唤起,引导用户去下载我们的app. 微信里屏蔽了 schema 协议,如果在微信中打开h5, ...

  4. JavaScript深入之从原型到原型链(本文转载)

    JavaScript深入之从原型到原型链(本文转载) https://github.com/mqyqingfeng/Blog.原文地址 构造函数创建对象 我们先使用构造函数创建一个对象: functi ...

  5. H5 唤起 APP的解决方案

    H5 页面唤起APP或跳转到下载APP的某个链接地址.总结如下: 在 IOS 中, 系统版本在 8 以下时,可以监听页面的 pagehide / visibilitychange 事件. 系统版本大于 ...

  6. h5移动网页唤起App

    最近这个困惑了很久,不断的有一些坑,目前还有疑问关于iOS唤起无效时会出现弹框的问题,这个最后再说 1.首先可能需要判断当前浏览器的来源(目前开发的App还没有上架,所以针对腾讯出品的大家广为人知的微 ...

  7. 从手机浏览器或者 APP 中跳转到微信并跳转到指定页原理及行业内幕详解

    相信很多朋友遇到过有些网站,可以直接通过一个连接就能让你的手机打开微信且跳转到某个指定的页面,许多程序员很好奇到底是怎么实现的,到处求这种方法的源码,在文本中我会介绍及剖析这种跳转实现的原理. 微信是 ...

  8. H5唤起app

    H5唤起app 1.判断是否在微信中打开 无论是在哪个平台的客户端Android/IOS,在微信的平台上访问都有一个问题,那就是无法启动客户端,这是微信为了安全性考虑的限制,android这边屏蔽sc ...

  9. 通过JS下载 or 唤起App

    判断唤起app的连接是否在WeChat中打开 let isWeiXin = navigator.userAgent.toLowerCase().indexOf('micromessenger') != ...

随机推荐

  1. layui之select的option叠加问题解决

    小编我在使用layui,在select的地方遇到了坑,select里的值居然无法清空,select里的option还有叠加问题,为了解决这个问题,也达到我的功能,我研究了下,让有同样需求的小伙伴不踩坑 ...

  2. Java - 16 Java 方法

    在前面几个章节中我们经常使用到System.out.println(),那么它是什么呢? println()是一个方法(Method),而System是系统类(Class),out是标准输出对象(Ob ...

  3. 基于Linux命令行KVM虚拟机的安装配置与基本使用

    背景 由于生产环境的服务器并不会安装桌面环境,简单操作的图形化安装也不适合批量部署安装.因此,我还是更倾向于在命令下安装配置KVM虚拟机.结合了一些资料和个人使用的状况,我大致列出了一些基本和常用的使 ...

  4. elasticsearch License 到期后更新步骤

    ELK下载安装后有一个月试用期,到期后需要更新License,且每个License有效期为 1 年,License过期前10天里相关log会一直出现,提醒用户更新,支持实时更新无需重启服务. 步骤: ...

  5. day24类的继承

    类的继承1 什么是继承    继承一种新建类的方式,新建的类称之为子类/派生类,被继承的类称之为父类\基类\超类    python中继承的特点:        1. 子类可以遗传/重用父类的属性   ...

  6. MySQL 中的三中循环 while loop repeat 的基本用法

    -- MySQL中的三中循环 while . loop .repeat 求 1-n 的和 -- 第一种 while 循环 -- 求 1-n 的和 /* while循环语法: while 条件 DO 循 ...

  7. SVN提交报错(SVN的bug)

    提交的时候报错: Failed to execute WebDAV PROPPATCHsvn: Commit failed (details follow):svn: At least one pro ...

  8. oozie 工作流调试及报错

    1.  oozie 调用sql文件的workflow 错误汇总: 1)hive2server密码错误.(有时设置可以无密码,有时需要登陆密码,有时是单独的hive2server密码) Connecti ...

  9. out.println与<%!%>的功能一样

    <%! public static final String DBDRIVER = "A"; public static final String DBURL = " ...

  10. ubuntu16.04搭建geodjango+postgresql+postgis的WebGIS框架(一)安装第三方空间库

    postgis是postgresql的空间扩展对象,它需要一些第三方库的支持.包括GEOS, PROJ.4 和 GDAL.我们首先安装这几个空间库. 在ubuntu系统终端执行:(预先装一些依赖的库) ...