H5唤醒app用到URL Scheme技术,例如微信扫一扫:weixin://dl/scan
除URL Scheme之外,还有Universal Link和App Links。
Universal Link是IOS特有,而App Links是安卓特有。
使用中常见问题及解决方案
- 可能会被app禁掉,比如微信,qq等
- ios9+ 禁止掉了iframe方式。
- ios及部分安卓浏览器会提示用户是否打开App,并且ios在未安装对应App的时候,会提示“打不开网页,因为该网址无效”
- h5无法感知是否唤醒成功
- 大部分浏览器需要用户手动触发链接,js自动触发无效
针对被app禁止掉的情况,通常会判断是否微信等app环境,然后提示用户浏览器内打开 针对ios9+ iframe 被禁掉的情况,判断下ios版本 针对h5无法感知是否唤醒成功的解决办法是,一段时间之后自动跳转下载页,或者是依赖setTimeout在浏览器进入后台后进程切换导致的时间延迟判断。
另外,如果手机没有安装此app,safari浏览器会直接弹出类似"浏览器打不开该网址”的描述,js层面无法做出失败回调,从而跳转app下载页。
现一般的技术方案,是做个定时器,2秒后,自动跳转app下载页。H5切换时,计数器的进程会中断,从而判断客户已安装app。
除此之外还有另外一种方案,美团的做法是,客户点击美团app的图标,则跳转到一个中间页,然后执行URL Scheme,在没有安装app的情况下,safari浏览器弹出无法打开该网址的提示,接着页面会展示两个按钮,一个是下载app按钮,另一个是打开app的按钮。
代码1
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> #btnLQ { width: 200px; height: 60px; display: block; margin: 300px auto; } { } </style> </head> <body> <div> <button id="btnLQ">在线开户1</button> </div> <script> var startTime = new Date().getTime(); var timeout = 2000; // 设置超时时间为500毫秒 function handleCopy() { var ua = window.navigator.userAgent; if (/iPhone|iPod|iPad/i.test(ua)) { window.location.href = "https://itunes.apple.com/cn/app/%E7%AB%8B%E6%A9%8B%E6%99%BA%E6%85%A7%E7%90%86%E8%B2%A1/id1395796104?mt=8"; } else { window.location.href = "https://embs.wlbank.com.mo/static/androidApk/wlbbank.apk"; } } function checkRedirect() { if (new Date().getTime() - startTime > timeout) { // 如果在timeout时间内页面没有被重定向,则认为目标应用未安装 console.log("未安装app"); handleCopy(); // 这里可以添加更多处理逻辑,例如提示用户下载应用等 } } document.getElementById("btnLQ").onclick = function () { try { window.location.href = "welllinkbank://com.bankscene.bes?moduleType=1&resourceUrl=¶ms={}&isLogin=0"; // window.location.href = "weixin://dl/scan" } finally { setTimeout(checkRedirect, timeout); } }; </script> </body> </html>
代码2
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> <style> #btnLQ { width: 200px; height: 60px; display: block; margin: 300px auto; } { } </style> <!-- <script src="https://cdn.jsdelivr.net/npm/eruda"></script> <script>eruda.init();</script> --> </head> <body> <div> <button id="btnLQ">在线开户2</button> </div> <script> document.getElementById("btnLQ").onclick = function () { //检查app是否打开 function checkOpen() { var _clickTime = +new Date(); function check(elsTime) { if (elsTime > 3000 || document.hidden || document.webkitHidden) { // alert("跳转app"); } else { // alert("即將跳轉下載頁.."); const ua = window.navigator.userAgent; if (/iPhone|iPod|iPad/i.test(ua)) { window.location.href = "https://itunes.apple.com/cn/app/%E7%AB%8B%E6%A9%8B%E6%99%BA%E6%85%A7%E7%90%86%E8%B2%A1/id1395796104?mt=8"; } else { window.location.href = "https://embs.wlbank.com.mo/static/androidApk/wlbbank.apk"; } } } //启动间隔20ms运行的定时器,并检测累计消耗时间是否超过3000ms,超过则结束 var _count = 0, intHandle; intHandle = setInterval(function () { _count++; var elsTime = +new Date() - _clickTime; if (_count >= 100 || elsTime > 3000) { clearInterval(intHandle); check(elsTime); } }, 20); } //在iframe 中打开APP 以下方法在safari中无效 // var ifr = document.createElement("iframe"); // ifr.src = "welllinkbank://com.bankscene.bes?moduleType=1&resourceUrl=¶ms={}&isLogin=0"; // ifr.style.display = "none"; window.location.href = "welllinkbank://com.bankscene.bes?moduleType=1&resourceUrl=¶ms={}&isLogin=0"; checkOpen(); document.body.appendChild(ifr); setTimeout(function () { document.body.removeChild(ifr); }, 2000); }; </script> </body> </html>
代码3:meta标签
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="refresh" content="0; url='welllinkbank://com.bankscene.bes?moduleType=1&resourceUrl=¶ms={}&isLogin=0'"> </head> <body style="display:none;"> <button>下载app</button> </body> </html>
代码4
if (isAndroid) { //安卓终端使用iframe iFrame = document.createElement("iframe"); iFrame.setAttribute("src", urls); iFrame.setAttribute("style", "display:none;"); iFrame.setAttribute("height", "0px"); iFrame.setAttribute("width", "0px"); iFrame.setAttribute("frameborder", "0"); document.body.appendChild(iFrame); // 发起请求后这个 iFrame 就没用了,所以把它从 dom 上移除掉 iFrame.parentNode.removeChild(iFrame); iFrame = null; // 如果用户没有安装APP,则提示用户去安装APP setTimeout(() => { window.location.href = "https://www.pgyer.com/A2fc"; // 这里可以自行写一个延时关闭的弹窗,也可以跳转至app下载地址 }, 2000); } else if (isiOS) { //iOS终端直接页面跳转 window.location.href = urls; // 如果用户没有安装APP,则提示用户去安装APP setTimeout(() => { window.location.href = "https://www.pgyer.com/A2fc"; // 这里可以自行写一个延时关闭的弹窗,也可以跳转至app下载地址 }, 2000); } else { window.location.href = urls; }