浅谈浏览器插件检测 和自定义协议的支持
前一阵子一直在折腾浏览器的插件检测和自定义协议的支持。
经过种种痛苦的折腾,算是对这一领域有了点浅显的认知。特此记录一下
一、背景知识
自定义协议:常用的协议有 http:// https:// ftp:// 等
然而我们也经常会遇到类似这样的协议连接
thunder:// 迅雷的
item:// itunes的
ed2k:// 电驴的
这样的协议是需要本地计算机安装软件与之接应, 实现相应操作的
也就是当你点一个类似的连接,浏览器会通知系统以何种程序处理该种协议的连接,这种对应是通过注册表来实现的
参考资料:http://www.cnblogs.com/Aricc/archive/2009/03/18/1415929.html
二、实现方案
要定义一个自定义协议,首先需要你有一款程序与之对应,
也就是说这个协议得有软件去处理,一般会是下载操作。
而自定义协议连接最终是显示在网页上的,最终这是网页与本地程序之间的交互。
而之间的桥梁就是浏览器。
那么要支持一个自定义协议,还需要去检测本地是否有支持该协议的处理程序。
这个能力的检测是要通过检测浏览器的插件来判断的。
也就是 装软件的时候同时给浏览器增加插件,以便标示系统有能力支持协议。
画一个流程图:
发布软件 和自定义协议——》安装软件同时给浏览器安装插件———》用脚本检测浏览器插件以判断支持情况————》点击自定义协议连接调用本地程序处理
三、插件检测
IE 可以通过尝试 new ActiveXObject(axname); 操作是否成功来判断插件存在情况
try {
var obj = new ActiveXObject(axname);
a = true;
} catch (e) {
a = false;
};
return a;
IE的另一种方法是 预先埋设一个 object 并查看该object的属性或者方法来判断本地是否有能力支持
比如apple itunes的object为: <object classID="CLSID:D719897A-B07A-4C0C-AEA9-9B663A28DFCB" width="1" height="1" id="iTunesDetectorIE" ></object>
Firefox Chrome 等浏览器可以通过遍历其plugin 查看pluginName是否符合来判断插件存在情况
if(navigator.plugins && navigator.plugins.length > 0) {
for( var b = 0; b < navigator.plugins.length; b++) {
var c = navigator.plugins[b];
var d = c.name;
if( new RegExp(plugname,'i').test(d)) {
a = true
}
}
}
return a
另一种方法是 通过mimetype 做判断
var mimetype = navigator.mimeTypes["application/"+plugname];
if(mimetype){
a = true;
} else{
a = false;
}
}
catch (e) {
a = false;
}
return a;
四、存在的问题:
IE操作activeX控件的时候 浏览器可能会出现小黄条提示 这可能跟你的浏览器设置相关,会有安全提示,这是无法避免的
也不要企图捕获小黄条出现的事件,这是安全提示,除非用户主动操作,其他手段无法干预
当你的插件在不同的域名下运行时,会重复提示,只有用户允许在该域名下运行时,提示才会消失。
当然如果你肯花钱,你可以做成 itunes的插件那样的,默认在任何域名下运行
五、具体应用的实现流程
进入页面,
浏览器判断
不同浏览器的插件支持检测
cookie记录检测结果
没有插件————》预加载弹窗提示资源
监测专用协议连接的点击情况
根据插件支持检测结果做相应操作
有插件————》调用本地程序处理
无插件(或者检测不到)————》 弹窗提示安装软件
六、关于强制调用
如果不能确定本地有没有相应程序支持,而强制将专用链接给浏览器处理会怎样?
Firefox Chrome 都有有好的提示界面,提示浏览器不知道采用何种程序处理该协议的链接
IE 不同 版本会有不同表现,这跟它们的安全级别相关。
首先所有的IE都会显示一个丑陋的界面表示浏览器打不开这个链接
IE6的 安全性能最差,你可以用一个隐藏的iframe 来调用这个专用链接,而不会看到报错信息,运气好的话你可以
调起本地程序
IE7 8 9 则提升了安全性能,如果用隐藏的iframe来调用不识别的链接时,无论嵌套几层,总会立即反映到最顶层
显示无法打开该链接,意在通知用户你在调用一个不识别的协议,可能会危害你的计算机安全。
IE9 第一次会报错,显示无法打开,而再次点击则不会重复显示无法打开的页面。
七、具体项目应用和代码实现
http://zhushou.360.cn/script/360mobilemgrdownload.js
示例地址:
自己的总结:可以通过写vbs文件,动态生成注册文件,然后执行注册文件,实现自定义协议的注册。
RelativeFolder = wshShell.CurrentDirectory
mychrome=RelativeFolder & "\files\MyChrome.exe"
mychrome=Replace(mychrome,"\", "\\")
c=RelativeFolder & "\注册插件.reg"
Set fso = CreateObject("scripting.filesystemobject")
Set myfile=fso.CreateTextFile(c,2,ture)
myfile.writeline "Windows Registry Editor Version 5.00"
myfile.writeline "[HKEY_CLASSES_ROOT\eZECM4HQ]"
myfile.writeline "@=""eZECM4HQ Protocol"""
myfile.writeline """URL Protocol""="""""
myfile.writeline "[HKEY_CLASSES_ROOT\eZECM4HQ\DefaultIcon]"
myfile.writeline "@="""& mychrome &",1"""
myfile.writeline "[HKEY_CLASSES_ROOT\eZECM4HQ\shell]"
myfile.writeline "@="""""
myfile.writeline "[HKEY_CLASSES_ROOT\eZECM4HQ\shell\open]"
myfile.writeline "@="""""
myfile.writeline "[HKEY_CLASSES_ROOT\eZECM4HQ\shell\open\command]"
myfile.writeline "@=""\"""& mychrome & "\"" \""%1\"""""
myfile.Close
WshShell.run chr(34)&c&chr(34),,true
var wsh = new ActiveXObject('WScript.Shell');
if (wsh){
var strDesktop = wsh.SpecialFolders(4);
var c="\""+strDesktop+"\\档案管理系统\"";
try{
var rev=wsh.Run(c);
if(rev!=0){//返回错误
}
}catch(e){
alert("没有找到相应的安装插件,稍候会自动下载,下载成功后,请运行安装。");
download();
return null;
}
close();
wsh = null;
}
}catch(e){
alert("由于您的安全策略影响,请点击页面\"手动下载\"下载插件");
return null;
}
}