转 浏览器自定义协议检测
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>test</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <iframe id="trigger_protocol_ifrm" style="display:none"></iframe> <input id="protocolTxt" type="text" value="" /> <input id="checkBtn" type="button" value="检测是否支持该协议" /> <script> document.getElementById('checkBtn').onclick = function(){ var url = document.getElementById('protocolTxt').value; launchApplication(url, function(){ alert('success'); }, function(){ alert('fail'); }); }; var isDone = true; var timeout; var assistEl = document.getElementById('checkBtn'); var triggerEl = document.getElementById('trigger_protocol_ifrm'); function done(){ isDone = true; assistEl.onblur = null; triggerEl.onerror = null; clearTimeout(timeout); } function launchApplication(url, success, fail){ if(!isDone)return; isDone = false; assistEl.focus(); assistEl.onblur = function(){ if(document.activeElement && document.activeElement !== assistEl){ assistEl.focus(); } else { done(); success(); } }; triggerEl.onerror = function(){ done(); fail(); }; try{ triggerEl.src = url; }catch(e){ done(); fail(); return; } timeout = setTimeout(function(){ done(); fail(); }, 1800); } </script> </body> </html>
function launchApplication(url, success, fail) { if('msLaunchUri' in navigator){//如果是windows8,IE10+,可以支持这种方式调起客户端。 navigator.msLaunchUri(url, success, fail); return; } if (!isDone) return;//如果上次调起客户端没有完成,则直接返回,防止重复调用。 isDone = false; assistEl.focus(); assistEl.onblur = function () { if (document.activeElement && document.activeElement !== assistEl) { assistEl.focus(); //防止用户因为随机操作,而误认为是调起了客户端。 } else { done(); success();//如果焦点元素,快速失去了焦点,说明客户端已经被调起。 } }; timeout = setTimeout(function () { done(); fail();//如果超过一定时间仍然没有变化,说明没有注册协议 },1200); triggerEl.onerror = function () { done(); fail();//进入错误事件回调函数说明没有注册协议 }; try { triggerEl.src = url; } catch(e) { done(); fail(); //捕获到异常说明没有注册协议 } }
上方法主要假定如果客户端调起,则页面会失去焦点。用这样的方式来“推测”客户端是否被调起。但这种做法并不准确。
有赖于客户端调起的速度,还可能会被一些特殊的操作干扰而导致判断错误。
对于Chrome浏览器,若不能启动指定的应用,请查看如下几点
6.1 自定义协议后的参数不能太短,最好超过三个字符,并且最好不要用一些常用的关键字.
6.2 配置Chrome的阻止的协议列表, 配置文件路径如下,不用的安装路径,还不用的用户,路径稍有不同:
C:\Users\liu\AppData\Local\Google\Chrome\User Data\Local State
打开此文件后,找到如下内容:
"protocol_handler": { "excluded_schemes": { "afp":true, "data":true, "disk":true, "disks":true, "file":true, "hcp":true, "iview":false, "javascript":true, "mailto":false, "ms-help":true, "ms-windows-store":false, "myapp":false, "news":false, "nntp":true, "shell":true, "snews":false, "tencent":false, "vbscript":true, "view-source":true,
确保我们自己定义的协议 myapp 后面的值为"false", 即不在被排除的列表中.