缘起
运营会给用户发一些营销和通知短信,短信会携带一个网址。领导希望打开对应网页的时候会弹窗询问客户是否使用app打开,能打开就直接在app打开了。
scheme
最常用的方式是 scheme
经过测试,我们app的协议是
<a href="cn.wangxiao.zhuntiku://zdwx?param=%7B%22Type%22%3A2%2C%22TypeAction%22%3A0%2C%22Data%22%3A%7B%7D%7D">123</a>
代码由三部分组成:
cn.wangxiao.zhuntiku://
。这个类似于http://
是一种协议- zdwx 。这个类似于
www.baidu.com
是url网址 - ?param=xxx。 携带的参数
我们可以在页面里创建一个 iframe 或者使用js 跳转页面。
如果有app的话就会提示是否打开
问题
- 有浏览器会直接报错,错误的页面
- 不是所有用户都安装了app
- 手机浏览器 Android Chrome 25+ 不再支持 scheme 只支持
intent://
协议,需要用户手动点击才能跳转 - 微信里不支持,除非是白名单,需要提示在页面里提示浏览器打开
<a href="intent://scan/#Intent;scheme=zxing;package=com.google.zxing.client.android;S.browser_fallback_url=http%3A%2F%2Fzxing.org;end"> Take a QR code </a>
<iframe href="intent://xxx" style="display: none;">></iframe>// 失效
<iframe href="strange://xxx" style="display: none;">></iframe>// 失效
intent 协议
intent://
scan/
#Intent;
scheme=zxing;package=com.google.zxing.client.android;
S.browser_fallback_url=http%3A%2F%2Fzxing.org;
end
这个玩意也有兼容问题:
引用别人的文章 https://www.jianshu.com/p/76eaa1e0c2b2
目前市面上大多第三方浏览器都是基于 Chrome 开发,这就带来了兼容性问题(没有条件覆盖所有的系统浏览器,这里只是有限测试的结果):
/blog/docs/images/1000.png#alt=img)
1、部分浏览器,只支持 协议手动唤起,如chrome、锤子。
2、部分浏览器只支持
scheme
唤起,如 UC 浏览器。3、大部分浏览器,同时支持
scheme
私有协议和intent://
协议 自动唤起。但,都没有按标准的intent://
协议来实现(除了 360 浏览器,给 360 点个赞):
- 有的浏览器在 App 没安装时并没有执行
S.browser_fallback_url
,而是跳转到应用市场如猎豹浏览器 4.46.3、乐视浏览器 1.2.1.29。- 有的浏览器不支持
S.browser_fallback_url
如搜狗浏览器、欧朋浏览器、猎豹浏览器。- 有的浏览器无论应用有无安装
S.browser_fallback_url
一直都会执行如 QQ 浏览器。所以对这部分浏览器,不能使用
intent://
协议。4、更奇葩者,二者都不支持,如百度浏览器。
第一种,手动唤起。
第二种,第三种,自定义 scheme
第四种,百度浏览器无解。
解决方式: 判断常用浏览器,如果是锤子和Chrome原生无解,只能避免误伤。
考虑到浏览器判断的难度,结合浏览器市场占有率的情况,我们最终的方案是暂时忽略
锤子系统浏览器、 Chrome 原生浏览器
这部分不支持自定义 scheme 自动唤起 �App
的用户。
链接直接唤起app
Android—deep links
如果是短信里直接唤起app,会弹窗提示用app打开还是浏览器打开。要多一次选择,所以在 android6开始支持 deep links
点击链接直达 app
iOS—universal links
ios得使用 universal links ,要不然还是打开浏览器
结论: 从短信直接唤起app能不能行?
- 安卓类用户 首选
deep links
安卓6+ 备选inten-filter
- iOS 用户首选
universal links
ios9+
用户需要区分,不好用,还是得打开网页,再唤起app
iframe
无法明确判断是否安装了app,可以使用 settimeout 尝试唤起app,如果没有唤起成功会触发下载行为
var url = {}
var iframe = document.createElement("iframe")
var body = document.body
iframe.style.cssText='display:none;width:0;height:0'
var timer = null
$('#btn').on("click",function(){
if(/MicroMessenger/gi.test(navigator.userAgent)){
// 引导浏览器打开
}else{
body.appendChild(iframe)
iframe.src = url.url
timer = setTimeout(function(){
window.location.href = url.down
},500)
}
})
pageshow 事件,页面显示时候触发。在load事件之后触发
pagehide
visibilitychange 页面隐藏,比如切换tab
document.hidden 页面是否隐藏
由于各个浏览器的支持情况不同,我们需要将这些事件都给绑定上,即使这样,也不一定能够保证所有的浏览器都能够解决掉这个小问题,实在没办法的事情就不管了。
参考链接