ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

非IE浏览器下ActiveX技术的替代方案

2021-03-27 21:59:04  阅读:270  来源: 互联网

标签:Web 浏览器 ActiveX 控件 本地 IE 页面


目录

一、NPAPI或PPAPI

二、伪协议

三、本地服务

四、总结



ActiveX是我们在做Web开发使经常使用的浏览器端技术,通过ActiveX控件,Web页面可以实现与计算机本地资源交互,实现特定功能。但实际上ActiveX控件技术是微软自家独有的Web页面扩展技术,它并不包含在W3C制定的HTML标准里面,所以也只有IE或使用IE内核的浏览器才支持它。。究其原因,ActiveX本质上是与Web应用的设计初衷相违背的,它模糊了客户端与服务端的边界,带来安全性、稳定性、兼容性和执行效率等问题。这也是IE在主流浏览器性能排名中总是排在后面的重要原因。但没有办法,由于Windows在桌面操作系统的统治地位,造成了ActiveX成为了事实上的行业标准,ActiveX控件技术一直是Web开发时实现本地资源交互功能的首选技术。

但随着技术和市场的变化,现在开发Web应用时要求支持Chrome等非IE浏览器已经成了标配,而这些浏览器又不支持ActiveX控件,那么需要页面与本地交互时用到有什么方法可以代替呢?今天就根据本人的实际开发经验和大家交流一下。另外,下面谈到的内容还是在桌面使用Windows系统的前提下。

一、NPAPI或PPAPI

说到上面那个问题,有经验的大神会说用NPAPI或PPAPI啦。没错,NPAPI或PPAPI是指Plugin API,即插件接口规范。按照这些规范开发的插件,就可以集成在浏览器里,然后Web页面再调用插件的接口,完成相应的功能。NPAPI/PPAPI与ActiveX控件实现的效果类似,但走的技术路线并不同。ActiveX控件修改的是Web页面,而NPAPI/PPAPI实质上通过修改浏览器实现特定的拓展功能。顺便说一下,其实IE也有类似的拓展开发接口。

NPAPI是由网景公司开发的,但因为NPAPI有很大的安全隐患,谷歌在其基础上开发了PPAPI,并且从Chrome 52版本后就不再支持NPAPI了。从技术上讲,使用PPAPI貌似应该是最正统的方案,但实际上,目前我看到使用了PPAPI的产品只有Adobe的Flash Player,可能是我孤陋寡闻,不过也从一个侧面说明了这项技术至少在国内,用的还是很少。

PPAPI上使用了沙箱技术,插件程序全部运行在沙箱里,在增强安全性的同时也带来了资源消耗的增长。另外,沙箱的诸多安全限制对于做密码应用开发,比如调用USB Key进行数字签名,会造成不小的困难。,而且现在Chrome已经不允许安装非商店的扩展了,也就是说,即使你基于PPAPI开发出了扩展插件程序,也想要上线到谷歌商店才能使用。综合以上几点,除非你的客户有特殊原因或你有一个强大的开发团队,或者你想做Flash这样级别的产品,不推荐使用NPAPI或PPAPI作为ActiveX控件的替代技术。

二、伪协议

相比高大上的PPAPI,伪协议就很接地气了。它利用浏览器打开HTTP协议的原理, “伪造”一种类似的协议,而这个协议实际上是与本地的某个可执行程序绑定。当浏览器访问以这个协议开头的URL时,就会打开绑定的本地可执行程序,实现页面与本地资源的交互。以一个打开PDF文档的页面为例子,在注册表设置以下键值:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\pdffile]

"URL Protocol"=""

[HKEY_CLASSES_ROOT\pdffile\shell]

[HKEY_CLASSES_ROOT\pdffile\shell\open]

[HKEY_CLASSES_ROOT\pdffile\shell\open\command]

@="\"D:\\eSealsPdf\\PdfReader\\Release\\PdfReader.exe\" %1"

它设置了一个名为“pdffile”的伪协议,这个伪协议与本地的PDF浏览器程序PdfReader.exe绑定。然后在Chrome等浏览器中访问如下URL:

"pdffile://www.neeq.com.cn/disclosure/2018/2018-10-09/1539075385_982462.pdf",浏览器会弹出如下提示(根据浏览器的不同提示会有所变化):

点击“打开PDFReader.exe”后,浏览器会启动程序,打开PDF文档,如下:

 

由此可见,伪协议的使用还是比较简单的。像我们熟悉的QQ,迅雷都采用这种方式在网页启动程序。但由于伪协议本质上打开一个程序,所以使用上还是会存在一些问题:首先是本地程序是单独启动的,因此从用户视角来看,程序窗体是弹出而不是嵌入在页面中的,这一点可能会使很多用户觉得不习惯,造成用户使用体验不好。二是程序与页面之间的数据交互问题。在上面的例子中,程序的输入参数可以由伪协议的URL传入,但如果需要程序将执行结果或输出参数返回给页面,就可能要费些周折。比如可以通过长链接轮询的方式,本地程序将执行结果发送并通知Web后台,后台再刷新前端页面。这些都无疑会增加开发的难度和工作量。

三、本地服务

在这几个方法中,本地服务是和ActiveX控件技术最契合的。说白了,它是通过开发一个本地的Web服务程序代替ActiveX控件,将原来ActiveX控件的COM接口变成本地的Web服务接口,而原来调用ActiveX控件接口的Java Script改造成调用Web服务接口的Java Script.

本地Web服务的开发方式有很多选择,一般是采用监听本地端口,对接受到的HTTP请求进行处理,并将处理的结果返回给页面。可以理解成开发一个简化版的HTTP服务器。

比如可以使用Winsock控件来监听端口,然后在控件的DataArrival消息处理函数里对接收到的数据进行处理。根据接收的数据执行相应的功能,最后将执行的结果构造成HTTP Response,再调用Send方法返回给调用方。

调用页面相应做如下改造,以实现数字签名为例:

function signmsg(msg, cert,type,callback) {

//先声明一个异步请求对象

var xmlHttpReg = null;

if (window.ActiveXObject || "ActiveXObject" in window) {//如果是IE

xmlHttpReg = new ActiveXObject("Msxml2.XMLHTTP");

} else if (window.XMLHttpRequest) {

xmlHttpReg = new XMLHttpRequest(); //实例化一个xmlHttpReg

}

//如果实例化成功,就调用open()方法,就开始准备向服务器发送请求

if (xmlHttpReg != null) {

if (!(window.ActiveXObject || "ActiveXObject" in window))

xmlHttpReg.onload = function () {

if (xmlHttpReg.status == 200)

callback(xmlHttpReg.responseText);

}//

//8888为监听端口

xmlHttpReg.open("post", "http://127.0.0.1:8888/Sign.method", false );

msg = msg.replace(/[\r\n]/g, "");

cert = cert.replace(/[\r\n]/g, "");

if (type == undefined)

msg = "msg: " + encodeURIComponent(msg) + "\r\ncert: " + cert + "\r\nend";

else

msg = "msg: " + encodeURIComponent(msg) + "\r\ncert: " + cert + "\r\nsigntype: " + type + "\r\nend";

//调用Web服务

xmlHttpReg.send(msg);

//得到服务返回数据

return xmlHttpReg.responseText;

}//

}//...

上面的代码也很好懂,就不再解释了。

使用这种方案也有其自身问题:一是本地服务启动问题。本地服务可以做成自启动,也可以做成Windows服务,不过这可能都会面临被一些安全软件,如360,认为是不安全程序而禁用的情况,这时就需要加入安全软件的白名单,这些无疑会带来使用上的门槛和不便。比较好的办法是在页面中需要调用Web服务接口之前,使用伪协议来启动本地服务程序,这样可以做到按需启动,降低被拦截的可能性。二是页面中的脚本需要访问本地服务,如上面的“http://127.0.0.1:8888/Sign.method”。这时如果Web页面的URL是由HTTPS开头的,部分浏览器可能会认为HTTP开头的本地服务不安全,因此会禁止脚本访问。当然,你可以开发一个支持HTTPS的本地服务,然后以HTTPS的方式访问。但开发这样的本地服务,并不是简单的事情。幸好,目前我只发现QQ浏览器存在这样的问题。当然,这个也并不是我们常说的跨域问题。

从开发成本和使用效果来讲,使用本地服务的方式还是比较合适的选择。对于已采用ActiveX控件的页面,可以比较方便的改造成使用本地服务。进一步说,即使桌面系统不是Windows,也可以采用这种本地服务的方法,而且已经实现调用服务的页面脚本可以不用做任何改造。

四、总结

综上所述,本文建议一般情况下,对于非IE浏览器,应采用本地服务或本地服务+伪协议的方式来替代ActiveX控件技术。

标签:Web,浏览器,ActiveX,控件,本地,IE,页面
来源: https://blog.csdn.net/dong123ohyes/article/details/115272415

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有