摘要:比如联系方式银行卡信用卡信息支付宝各大商城的账户密码照片甚至行程与位置信息等。针对这个问题,苹果使用了名为沙盒的机制应用只能访问它声明可能访问的资源。
h5唤醒APP功能
最近遇到一个需求,需要在从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 标签中打开。
打开App 打开应用
点击上面的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,该方案兼容性不是特别好吧。要做出一个比较完美的方案还需要细细去钻研,还需要不停地去搬砖~不说了,搬砖去了~
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/54769.html
摘要:有好的想法可以评论一下。下面放相关代码先走毫秒后调用链接这里放相关链接终端高德苹果和安卓头部不一样百度苹果和安卓头部不一样 前几天,联合黑卡反馈了一个需求,需要在H5中打开百度APP或者是高德APP,于是我在网上查了相关文档,下面放上链接: 1.高德地图 2.百度地图 具体思路就是点击选择地图的时候,先去请求APP链接,800毫秒后无响应,再跳转至H5链接。这样的做法有一点不好就...
摘要:前言在写移动端页面会遇到唤醒的需求一般都是通过协议唤起的这里记录一下代码片段以新浪微博为例其协议为这些协议需要自己去收集或者去官方查询有些分和有些应用又不分这个根据终端做处理即可测试地址微博微博个人主页跳转代码手机装了就打开没有就跳转页面或 前言 在写移动端页面会遇到唤醒App的需求, 一般都是通过scheme协议唤起的,这里记录一下 代码片段 以新浪微博为例: 其协议为 sinawe...
阅读 1925·2021-11-24 09:39
阅读 3514·2021-09-28 09:36
阅读 3281·2021-09-06 15:10
阅读 3433·2019-08-30 15:44
阅读 1153·2019-08-30 15:43
阅读 1796·2019-08-30 14:20
阅读 2712·2019-08-30 12:51
阅读 2030·2019-08-30 11:04