本文做者:Mr.Luo ,贝聊前端经理。本文同时发布于做者 我的博客 。javascript
因为网页传播的便捷性,从网页向APP导流几乎是全部APP厂商都会采用的推广手段,具体来讲就是在网页上提供一些触发点(例如按钮、连接),用于跳转到APP。html
早期的应用跳转只能经过「URL Scheme」实现。例如经过下面这个「URL Scheme」,就能够跳转到「贝聊APP」:前端
ibeiliao://java
在网页中调用「URL Scheme」也有多种方法:web
<!-- 方案一:连接跳转 -->
<a href="ibeiliao://">打开贝聊</a>
<!-- 方案二:JS跳转 -->
<a href="javascript:location.href='ibeiliao://'">打开贝聊</a>
<!-- 方案三:iframe调用 -->
<span id="open-ibeiliao">打开贝聊</span>
<script> document.getElementById('open-ibeiliao').onclick = function() { var iframe = document.createElement('iframe'); iframe.src = 'ibeiliao://'; iframe.style.display = 'none'; document.body.appendChild(iframe); setTimeout(function(){ document.body.removeChild(iframe); }, 3000); }; </script>
复制代码
本来「方案三」是最受欢迎的,由于在没有安装对应APP的状况下,另外两个方案在iOS Safari下都会出现「浏览器没法打开网页」的弹框。浏览器
然而,「方案三」是最早“阵亡”的,最先是在iOS 9中的Safari失效,后来在某些安卓机的浏览器也不行了,因此目前只能用「方案一」和「方案二」,而iOS Safari下的那个弹框也就没法避免了。微信
理论上,「URL Scheme」能够在任何浏览器以及APP中的WebView使用,但实际上倒是被大量APP封杀,几乎是只能在浏览器类的APP中使用。由于大部分厂商都不但愿用户离开本身的APP。app
前文提到了一个问题,万一设备上没有安装要跳转的APP,那怎么办呢?正常来讲,应该要跳到该APP的下载页。然而,这里面最大的难题是:网页端基本上没法获知当前设备是否已安装某个APP(之因此加上“基本”二字,是由于网页在微信内运行时,可经过调用微信内部的JS API实现此功能,但该API只对腾讯的“关系户”开放)。函数
后来,人们想出了一种解决方案:在使用「URL Scheme」跳转的同时,经过定时器在必定时间以后跳转到下载页。假若设备上有安装APP,就会跳到APP,不然在必定时间后就会跳到下载页。ui
<span id="open-ibeiliao">打开贝聊</span>
<script> document.getElementById('open-ibeiliao').onclick = function() { window.location.href = 'ibeiliao://'; setTimeout(function() { window.location.href = 'https://mobile.ibeiliao.com/download'; }, 1000); }; </script>
复制代码
这么作基本上是达到了目的,可是有两处体验问题仍然没法解决:
前文有说起,「URL Scheme」被大量APP封杀,其中就包括经常使用的QQ和微信,可是没有谁会放弃这两个重要渠道,因此仍是得想辙。
最无奈的解决方案就是提示用户「用浏览器打开网页」,继而让用户在浏览器中打开APP。然而,这对非IT人士来讲,操做起来仍是有一点繁杂的。
另外一种好一点的作法是,先跳转到腾讯的「应用宝」,「应用宝」会根据设备是否已装APP去执行打开或者下载操做。固然,这种作法须要把APP传到「应用宝」,并且只对腾讯系的APP有效;对于其余APP,仍然只能提示「用浏览器打开网页」。
最后一个解决方案就是下文要讲述的「Universal Links」。
「Universal links」,中文翻译为「通用连接」,从iOS 9开始支持,仅经过普通的https请求就能跳转到指定的应用。
开发者能够把应用的下载页地址配置为一条通用连接,这样,用户在进入下载页时:
最重要的是,经过「通用连接」,即便在微信、QQ内,也能如丝般顺滑地跳到自家APP。你们都觉得这是系统级别的处理,没法被任何APP封杀,直到不久前的一天,它在微信下跪了。。。根据某大神的分析,苹果仍是给「通用连接」留下了“后门”可让其失效。
而在Android系统下,也有相似的技术,即App Links,从Android M开始支持。但因为国内安卓版本碎片化比较严重,因此应用还不怎么普遍。
讲到这,先小结一下应用跳转的实现方案。
要注意的是,所谓的「其余APP」是没法准确检测的,只能根据APP在User Agent中增长的特殊关键字(例如新浪微博的「Weibo」)逐个判断。
需求是无止境的,能从网页进入APP只是开始,下一步就是跳转到指定页面。这里所说的指定页面,多是原生的页面,也多是某个网页。这个过程的关键在于打开APP时如何把页面路径传过去。
先从「URL Scheme」提及。咱们能够给「URL Scheme」加上路径和参数,例如:
my-app://open?url=https%3A%2F%2Fcn.bing.com%2F
APP端只要解析参数,继而打开对应的页面便可。对于「Universal Links」来讲,也是同理:
正如上文所说,「URL Scheme」和「Universal Links」都被微信封杀了。若是经过「应用宝」中转,上述url参数是没法传到APP的。在这种状况下,就得寻找一个微信WebView和APP均可以共同读写的空间来传递数据,例如剪贴板。下面这个JS函数能够实现对剪贴板的写入:
function copyToClipboard(content) {
var textarea = document.createElement('textarea');
textarea.style.position = 'absolute';
textarea.style.left = '-1000px';
textarea.style.top = '-1000px';
textarea.value = content;
textarea.readOnly = true;
document.body.appendChild(textarea);
textarea.select();
textarea.setSelectionRange(0, textarea.value.length);
var result = false;
try {
result = document.execCommand('copy');
} catch (e) {
}
document.body.removeChild(textarea);
textarea = null;
return result;
}
复制代码
跳转到APP的应用宝地址以前,把要打开的页面地址以约定好的格式写入剪贴板:
copyToClipboard('my-app:open?url=https%3A%2F%2Fcn.bing.com%2F');
location.href = 'my-app的应用宝地址';
复制代码
经过「应用宝」打开APP后,APP端按照约定格式解析剪贴板内容打开对应的页面便可。
这里有一个细节:为何不直接以完整的「my-app://open?url=」写入剪贴板,而要特地去掉「//」?这是由于在Android系统下,某些浏览器APP会把剪贴板中的「URL Scheme」识别为网址,而后提示用户是否打开。对于用户来讲,点击「打开APP」出现这个提示,就有点莫名其妙了。
固然,「剪贴板方案」也存在一些问题:
若是不想用「剪贴板方案」,仍是能够提示用户用浏览器打开页面的。具体如何取舍,就看各自产品经理的决定了。