前言

需求背景:一个web下载页面,需要检测pc是否安装了客户端软件(windows软件)。网页上有一个打开客户端按钮。若安装了客户端软件,则直接打开,否则下载软件。支持web下载页面在iframe下

打开客户端的方法

通过客户端软件在注册表注册的自定义协议打开。例如: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后还没弹窗,判断没有安装客户端。

js检测客户端是否安装的更多相关文章

  1. 利用 html js判断 客户端是否安装了某个app 安装了就打开 否则跳转到gp

    三种方式 方式一:简单的进行打开app,延时操作若未打开直接跳gp function isInstalled(){ var urlFrag = 'somepars'; var the_href = ' ...

  2. 如何用js检测手机是否安装某个app

    问题描述 如果本地安装了app那么直接打开,否则苹果要跳转到app-store,安卓则要跳到对应的市场 解决方案 一 //html代码中 的 a 标签,以微信为例,默认的是调用weixin schem ...

  3. js 检测客户端网速

    <!doctype html> <html> <head> <meta http-equiv=Content-Type content="text/ ...

  4. JS 检测客户端断网情况

    常用方法 1 navigator.onLine 2 window.addEventListener() 3 获取网络资源 4 ajax请求 1. navigator.onLine 只会在机器未连上路由 ...

  5. 一个JS判断客户端是否已安装某个字体(Only IE)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. H5案例分享:使用JS判断客户端、浏览器、操作系统类型

    使用JS判断客户端.浏览器.操作系统类型 一.JS判断客户端类型 JS判断客户端是否是iOS或者Android手机移动端 通过判断浏览器的userAgent,用正则来判断手机是否是ios和Androi ...

  7. Node.js系列基础学习----安装,实现Hello World, REPL

    Node.js基础学习 简介 简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台.Node.js是一 ...

  8. Node.js的简介和安装

    一.Node.js的简介和安装 a)       什么是Node.js? Node.js是一个开发平台 让JavaScript运行在服务器端的开发平台 ---简单点说就是用JavaScript写服务器 ...

  9. 检测客户端显示器分辨率、浏览器类型和客户端IP

    原文:检测客户端显示器分辨率.浏览器类型和客户端IP 下面的代码实现了检测客户端显示器分辨率.浏览器类型和客户端IP的功能.你可以把客户端信息保存到Session,ViewState等中以便在其它的页 ...

随机推荐

  1. Json文件解析(下)

    Json文件解析(下) 代码地址:https://github.com/nlohmann/json   从STL容器转换 任何序列容器(std::array,std::vector,std::dequ ...

  2. gradle 混合编程java、scala、kotlin、groovy

    众所周知,java是基于JVM的开发语言,但能够在JVM上运行的开发语言不仅仅有java,目前还有很热门的kotlin(kotlin不仅仅只能开发Android).scala.groovy等等.目前国 ...

  3. 【NX二次开发】Block UI 表达式

    属性说明 常规         类型 描述     BlockID     String 控件ID     Enable     Logical 是否可操作     Group     Logical ...

  4. 【VBA】判断文件是否存在

    效果: 源码: Sub 判断文件是否存在() Dim strcfg As String strcfg = "D:\a.cfg" If Dir(strcfg, vbDirectory ...

  5. Django基础之自定义分页器

    自定义分页器 针对批量插入的数据,我们在前端展示的时候发现一个很严重的问题,一页展示了所有的数据,数据量太大,查看不方便 针对数据量大但又需要全部展示给用户观看的情况下,我们统一做法都是做分页处理 分 ...

  6. MySQL 最佳实践 —— 高效插入数据

    当你需要在 MySQL 数据库中批量插入数百万条数据时,你就会意识到,逐条发送 INSERT 语句并不是一个可行的方法. MySQL 文档中有些值得一读的 INSERT 优化技巧. 在这篇文章里,我将 ...

  7. 身为一枚优秀的程序员必备的基于Redis的分布式锁和Redlock算法

    1 前言 今天开始来和大家一起学习一下Redis实际应用篇,会写几个Redis的常见应用. 在我看来Redis最为典型的应用就是作为分布式缓存系统,其他的一些应用本质上并不是杀手锏功能,是基于Redi ...

  8. SQL Sever提权

    前言:渗透测试中提权是较为重要的环节,若以低权限身份进行后渗透,测试出的问题相对于高权限的质量会低很多,从一个普通用户,通过手段让自己变为管理员,也可利用操作系统或者应用程序中的错误,设计缺陷或者配置 ...

  9. 小白学k8s(9)-gitlab-runner实现go项目的自动化发布

    gitlab构建CI/CD 准备 docker部署gitlab 使用二进制部署gitlab-runner gitlab-runner注册 配置Variables 简单先来个测试 开始构建 遇到的报错 ...

  10. Unity 消消乐开发思路

    以简单的方式讲述游戏开发思路,暂时没有实践,如有错误,欢迎各位大佬指错 关卡数据保存方式 数据保存我选用json,可读性强,解析快 消消乐物体处理方式 消消乐物体我将以预制体的方式使用(把物品拖到As ...