来源:
最近在配合移动端做几个详情页h5分享页面,需要调取App并跳转至app详情页, 如果没有安装App,需要判断引导至下载页面。
参考文档:
https://juejin.im/post/5b7efb2ee51d45388b6af96c
URL Scheme —— 唤端媒介
[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 是不现实的。
主要注意点:
1、和原生移动端协商好调取app的Url schema和参数:investnote://chengan:8888/main?note_id=991&open_type=1
2、判断是否是微信,因为微信不能直接调取app,需要引导用户用浏览器打开,andriod有默认的引导页可以隐藏,ios需要自己设计
3、大体上判断安卓和ios两种设备,再做不同处理
4、iOS版本在9以上会默认弹出一个打开APP的弹出框,通过延时来打开app的方法就不适用了
1<script lang="javascript"> 2 3 var createIframe=(function(){ 4 var iframe; 5 return function(){ 6 if(iframe){ 7 return iframe; 8 }else{ 9 iframe = document.createElement('iframe'); 10 iframe.style.display = 'none'; 11 document.body.appendChild(iframe); 12 return iframe; 13 } 14 } 15 })() 16 17 /*判断是否是ios9以上*/ 18 function isIOS9() { 19 //获取固件版本 20 var getOsv = function () { 21 var reg = /OS ((\d+_?){2,3})\s/; 22 if (navigator.userAgent.match(/iPad/i) || navigator.platform.match(/iPad/i) || navigator.userAgent.match(/iP(hone|od)/i) || navigator.platform.match(/iP(hone|od)/i)) { 23 var osv = reg.exec(navigator.userAgent); 24 if (osv.length > 0) { 25 return osv[0].replace('OS', '').replace('os', '').replace(/\s+/g, '').replace(/_/g, '.'); 26 } 27 } 28 return ''; 29 }; 30 var osv = getOsv(); 31 var osvArr = osv.split('.'); 32 //初始化显示ios9引导 33 if (osvArr && osvArr.length > 0) { 34 if (parseInt(osvArr[0]) >= 9) { 35 return true 36 } 37 } 38 return false 39 } 40 41 //判断是否是微信 42 function isWeiXin(){ 43 var ua = window.navigator.userAgent.toLowerCase(); 44 if(ua.match(/MicroMessenger/i) == 'micromessenger'){ 45 return true; 46 }else{ 47 return false; 48 } 49 } 50 51 function checkIsweixin(){ 52 var mask = document.getElementById('mask') 53 var openBtn = document.getElementById('openBtn') 54 if(isWeiXin()){ 55 mask.setAttribute('style','display:block'); 56 openBtn.setAttribute('style','display:block'); 57 return false 58 } 59 mask.addEventListener('click', function(){ 60 this.setAttribute('style','display:none'); 61 openBtn.setAttribute('style','display:none'); 62 }) 63 openBtn.addEventListener('click', function(){ 64 mask.setAttribute('style','display:none'); 65 this.setAttribute('style','display:none'); 66 }) 67 openApp(); 68 } 69 70 function openApp(){ 71 var localUrl="investnote://chengan:8888/main?note_id=991&open_type=1"; 72 var openIframe=createIframe(); 73 var u = navigator.userAgent; 74 var isIos = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端 75 var isAndroid= u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端 76 var isChrome = window.navigator.userAgent.indexOf("Chrome") !== -1; 77 if(isIos){ 78 if(isIOS9()){ 79 //判断是否为ios9以上的版本,跟其他判断一样navigator.userAgent判断,ios会有带版本号 80 /* localUrl=createScheme({type:1,id:"sdsdewe2122"},true);//代码还可以优化一下*/ 81 window.location.href = localUrl; 82 return; 83 } 84 //判断是否是ios,具体的判断函数自行百度 85 window.location.href = localUrl; 86 var loadDateTime = Date.now(); 87 setTimeout(function () { 88 var timeOutDateTime = Date.now(); 89 if (timeOutDateTime - loadDateTime < 1000) { 90 window.location.href = "https://itunes.apple.com/cn/app/%E6%8A%95%E8%B5%84%E4%BA%91/id1376471541?mt=8"; 91 } 92 }, 25); 93 }else if(isAndroid){ 94 //判断是否是android,具体的判断函数自行百度 95 if (isChrome) { 96 //chrome浏览器用iframe打不开得直接去打开,算一个坑 97 window.location.href = localUrl; 98 } else { 99 //抛出你的scheme 100 openIframe.src = localUrl; 101 } 102 var loadDateTime = Date.now(); 103 setTimeout(function () { 104 var timeOutDateTime = Date.now(); 105 if (timeOutDateTime - loadDateTime < 1000) { 106 window.location.href = "http://chengantech.com/download/"; 107 } 108 }, 25); 109 }else{ 110 //主要是给winphone的用户准备的,实际都没测过,现在winphone不好找啊 111 openIframe.src = localUrl; 112 setTimeout(function () { 113 window.location.href = "http://chengantech.com/download/"; 114 }, 500); 115 } 116 } 117 118 var appBtn = document.getElementById('appBtn') 119 appBtn.addEventListener('click', checkIsweixin ) 120 121 </script>
页面大致布局如下:
11 <div class="note-fixfoot"> 22 <a class="note-share-button" id="appBtn">用APP打开</a> 33 </div> 44 <div id="mask"></div> 55 <div id="openBtn"></div>
加入简单的样式:
1.note-fixfoot{ 2 position: fixed; 3 bottom: 0; 4 width: 100%; 5 height: 60px; 6 background: url('./share_wechat@3x.png') no-repeat center; 7 background-size: 100% 100%; 8 } 9 .note-fixfoot .note-share-button{ 10 border-radius:4px; 11 display: block; 12 width: 100px; 13 height: 34px; 14 position: absolute; 15 right: 20px; 16 top: 14px; 17 background:rgba(94,105,199,1); 18 color: #ffffff; 19 text-align: center; 20 line-height: 34px; 21 text-decoration: initial; 22 font-weight: normal; 23 font-size: 14px; 24 } 25 html,body{ 26 overflow: hidden; 27 } 28 #mask{ 29 height:100%; 30 width:100%; 31 position:fixed; 32 top:0; 33 z-index:9; 34 opacity:0.8; 35 filter: alpha(opacity=80); 36 background-color:#000; 37 display: none; 38 } 39 #openBtn{ 40 width: 90%; 41 height: 30.5%; 42 color: #ffffff; 43 left: 5%; 44 top: 0; 45 font-size: 14px; 46 position: absolute; 47 margin-top: -15px; 48 cursor: pointer; 49 background: url('./android.png') no-repeat center; 50 background-size: contain; 51 border-radius: 5px; 52 text-align: center; 53 z-index: 10; 54 border-bottom-left-radius: 10px; 55 border-bottom-right-radius: 10px; 56 overflow: hidden; 57 background-color: #ffffff; 58 display: none; 59 }