通过浏览器打开某个客户端,需要检测看客户端是否已经安装过了,未安装则提示安装该客户端,已安装则直接打开
打开客户端的方法
通过客户端软件在注册表注册的自定义协议打开。例如:js代码location.href = 'baseonline://';
查看注册表方法: 在键盘上按“win+R”,打开运行窗口,在里面输入regedit,回车即可进入注册表编辑器
实现
方案1: 首先github上找到这个方案https://github.com/ismailhabib/custom-protocol-detection。对多个浏览器都实现了,基本都是hack方法。不足点是,若检测页面在iframe里面,谷歌浏览器的检测方法不起作用。如果检测页面不在iframe下,方案1就能满足使用
方案2:针对所在检测页面是iframe下的页面。找到另外一个方法去实现。在谷歌浏览器测试通过。其他的没测。
由于方案2只在谷歌测试过,可以把方案1和方案2结合使用。覆盖更多浏览器类型
方案2的具体实现
/** * uri 打开客户端的uri * failCb 打开客户端失败回调 * successCb 打开客户端成功回调 */ function openUriWithInputTimeoutHack(uri, failCb, successCb) { let target = document.createElement('input') target.style.width = '0' target.style.height = '0' target.style.position = 'fixed' target.style.top = '0' target.style.left = '0' document.body.appendChild(target) target.focus(); var handler = _registerEvent(target, "blur", onBlur); console.log('focus') function onBlur() { console.log('blur') successCb && successCb() handler.remove() clearTimeout(timeout) document.body.removeChild(target) }; //will trigger onblur location.href = uri // Note: timeout could vary as per the browser version, have a higher value var timeout = setTimeout(function () { console.log('setTimeout') failCb && failCb() handler.remove() document.body.removeChild(target) }, 1000); } function _registerEvent(target, eventType, cb) { if (target.addEventListener) { target.addEventListener(eventType, cb); return { remove: function () { target.removeEventListener(eventType, cb); } }; } else { target.attachEvent(eventType, cb); return { remove: function () { target.detachEvent(eventType, cb); } }; } } // 测试 let protocalUrl = `baseonline://` openUriWithInputTimeoutHack(protocalUrl, () => { console.log('检测到,未安装客户端') }, () => { // 浏览器弹窗提示 console.log('检测到:已安装了客户端') })
原理:同样是hack方法,利用input聚焦失焦去判断。点击打开客户端按钮,input聚焦。
1. 如果浏览器检测到本地系统有对应的注册码,则会弹窗提示是否打开客户端软件,input失去焦点,判断安装了客户端。
2. 否则1s后还没弹窗,判断没有安装客户端。