IE ActvieX更新产生影响的解决办法
一、问题背景和影响范围
由于专利问题,Microsoft 将被迫更改 IE 处理 ActiveX 控件的交互方式。所以Microsoft 即将发布一个用于 Microsoft Windows XP Service Pack 2 (SP2) 和 Microsoft Windows Server 2003 Service Pack 1 (SP1) 的 Microsoft Internet Explorer 6 的软件更新。据悉该更新将于6月2日正式开始。此更新可更改 Internet Explorer 处理某些使用 ActiveX 控件的网页的方式。使用 ActiveX 控件的程序包括以下这些:
- Adobe Reader
- Apple QuickTime Player
- Macromedia Flash
- Microsoft Windows Media Player
- Real Networks RealPlayer
- Sun Java Virtual Machine
安装此更新后,在启用 ActiveX 控件之前,您无法从某些网页与这些控件交互。要启用 ActiveX 控件,请手动单击该控件。Web 开发人员还可以使用其他技术来更新他们的网页。有关这些技术的更多信息,请访问下面的 MSDN 网站:http://msdn.microsoft.com/ieupdate
作为此 Internet Explorer 更新的一部分,Microsoft 会将更新发布到 Windows XP 和 Windows Server 2003 的当前版本中。所有客户端操作系统都将得到更新。这些客户端操作系统包括:
- Windows XP Starter Edition
- Windows XP Home Edition
- Windows XP Professional Edition
- Windows XP Tablet PC Edition
- Windows XP Media Center Edition
- Windows XP Professional for Embedded Systems
目前,Microsoft 尚未发布针对早期版本的 Internet Explorer、Windows Server 2003 或 Windows XP 的更新。但 Microsoft 以后可能会发布针对这些早期版本的更新。
二、产生的问题和表现
当网页用APPLET、EMBED和OBJECT标签下载的activeX控件,在控件的用户接口在用户激活之前是被阻止的。如果一个页面用这些标签下载多个控件,每个控件都需要分别被激活。

当一个控件处于未激活状态,它不会响应用户的输入,它只会执行操作,但不包括交互部分。当一个未激活的控件被创建,IE会用不同的技术来阻止键盘和鼠标的触发。例如,打开一个包含Flash的页面,Flash开始播放,但是它不会相应用户的交互请求,比如点击这个Flash而跳转到相应的URL,而是出现一个“单击以激活并使用此控件”,只有点击出发该控件,再次单击才出发跳转。
注意,控件不响应用户的直接交互,但相应脚本的请求。
激活一个交互控件可以点击,也可以通过Tab键设定焦点后按回格(Backspace)键或回车(Enter)键。

一些独立窗口的控件在IE中运行之前,会出现一个提示。用户需要点击信息窗口中的按钮来运行这个控件。控件下载后,不在需要激活。
下面的控件具有这种行为:
- Virtools™ Web Player from Virtools SA
- Macromedia Shockwave Player™ from Adobe Systems Inc.
- QuickTime™ from Apple Computer, Inc.
所以页面运行时可能出现的问题有:
- 滚动
- 当使用鼠标轮在包含交互式控件的页面中滚动时,该控件可能无法正确显示。
- 抽象窗口工具包
- 据报告,在用户界面中使用抽象窗口工具包 (AWT) 类的 Java 程序中存在访问冲
- 透明 Flash
- 整页广告虽然消失,但焦点框仍在。在这种情况下,控件仍在原位置,但却是透明的。因此,关联的覆盖窗口留 在页面上。
- DHTML 菜单
- 当展开一个 DHTML 菜单时,该菜单可能出现在 ActiveX 控件的顶部。在这种情况下,如果单击该菜单,则会启用该控件而不是访问 DHTML 菜单。覆盖窗口具有最高的 Z 顺序。因此,此窗口收到鼠标单击消息。
- 在加载之前进行提示的控件
- 在将某些控件加载到网页时,此更新的功能不会正确屏蔽这些控件。Macromedia Shockwave Director、QuickTime Player 和 Virtools Web Player 中使用的控件都属于这类控件。当 Windows 确定某个控件处于非活动状态时,系统会在加载该控件之前提示用户。
- 控件上的 CSS 属性
- 对于隐藏的控件,或者显示模式虽然设置为“无”但却具有尺寸大小的控件,当您将指针在它们上面移动时,将显示焦点框。
三、解决办法
虽然activeX控件不响应用户的直接交互,但相应脚本的请求,所以目前看到的解决方案都是通过外部的脚本来实现的。
1、Microsoft的解决方案
MS建议用外部的JScript文件下载控件实现用户可以直接和控件交互的问题。这个JScritpt文件必须是外部文件,如果直接写入网页HTML文件中,将不起作用。不能用JScript函数或者服务端脚本控制控件是否激活。具体实现方法如下:
1)使用document.write下载控件。
注意,不能在外部脚本文件通过 writeln函数来实现,因为该函数是把脚本插入到原始的HTML文档中。
<!-- HTML File -->
<html>
<body leftmargin=0 topmargin=0 scroll=no>
<script src="Embed.js"></script>
</body>
</html>
// embed.js
document.write('<embed src="examplecontrol">')
外部文件也可以通过修改一个标签的outerHTML的属性来实现。
<!-- HTML File -->
<html>
<body>
<div>
<script src="embedControlOuterHTML.js"></script>
</div>
</body>
</html>
// embedControlOuterHTML.js
embedControlLocation.outerHTML = '<embed src="examplecontrol">';
2)用 document.createElement创建Object标签下载activeX控件。
注意:当用document.createElement在一个页面创建Object和Embed标签,要仔细创建标签和初始化它的属性,在通过新标签下载activeX控件前加入页面的DOM中。详细信息可以查看MS的createElement文档。
<!-- HTML File -->
<html>
<body>
<div id="DivID">
<script src="createElementExplicit.js"></script>
</body>
</html>
// createElementExplicit.js
var myObject = document.createElement('object');
DivID.appendChild(myObject);
myObject.width = "200";
myObject.height = "100";
myObject.classid= "clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6";
myObject.URL = "example.wmv";
myObject.uiMode = "none" ;
3)当有特别参数时,用innerHTML和JScript来下载activeX控件。
<!-- HTML File -->
<html>
<head>
<script src="external_script.js" language="JScript"></script>
</head>
<body>
<div id="EXAMPLE_DIV_ID">
This text will be replaced by the control
</div>
<script language="JScript">
CreateControl( "EXAMPLE_DIV_ID",
"clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6",
"EXAMPLE_OBJECT_ID", "600", "400", "example.wmv",
"-1")
</script>
</body>
</html>
// external_script.js
function CreateControl(DivID, CLSID, ObjectID,
WIDTH, HEIGHT, URL, AUTOSTART)
{
var d = document.getElementById(DivID);
d.innerHTML =
'<object classid=' + CLSID + ' id=' + ObjectID +
' width=' + WIDTH + ' height=' + HEIGHT +'>
<param name="URL" value=' + URL + '>
<param name="autoStart" value=' + AUTOSTART + '/>';
}
2、Adobe的解决方案
针对其产品 Macromedia Flash, Shockwave, or Adobe Acrobat files的解决方法。
- 当只有一个嵌入内容或少量的嵌入内容时,直接用一个独立的外部JS文件来下载activeX控件。
- 创建外部文件 foo.js
function RunFoo() { document.write('<object classid="clsid:D27CDB6E..." ...>\n'); document.write('<param name="movie" value="foo.swf" />\n'); document.write('</object>\n'); } - 把foo.js加入相关页面的head标签中
<script src="[path]/foo.js" type="text/javascript"></script> - 用下面代码替换 <object> , <embed> 和 <applet>标签<script type=”text/javascript”>RunFoo();</script>
- 创建外部文件 foo.js
- 当嵌入大量的活动内容,且嵌入方式多样,下面是一种很好的解决方案。
- 下载Adobe提供的必须js文件。该文件包括三个部分:
- AC_RunActiveContent.js:针对 Flash 和 Shockwave 嵌入内容的;
- AC_ActiveX.js:针对其他的嵌入内容;
- SampleActiveContent.html:使用例子。
- 把AC_RunActiveContent.js加入相关页面的head标签中
<script src="[path]/AC_RunActiveContent.js” type=”text/javascript”></script> - 用下列函数来表达Object和Embed标签中的内容,并取代相关标签。
用于Flash
AC_FL_RunContent( "att1Name","att1Value", "att2Name","att2Value", ... "attnName","attnValue" );用于 Shockwave
AC_SW_RunContent( "att1Name","att1Value", "att2Name","att2Value", ... "attnName","attnValue" );例如:
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="550" height="400" align="middle"> <param name="allowScriptAccess" value="sameDomain" /> <param name="movie" value="foo.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#ffffff" /> <embed src="foo.swf" quality="high" bgcolor="#ffffff" width="550" height="400" name="foo" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> </object> <script type="text/javascript" > AC_FL_RunContent('codebase','http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0', 'width','550','height','400','align','middle','src','foo','quality','high','bgcolor','#ffffff','name','foo', 'allowscriptaccess','sameDomain','pluginspage','http://www.macromedia.com/go/getflashplayer','movie','foo' ); </script> - 针对不支持script的浏览器,标签表达内容可以放入<noscript>标签中。
3、使用deconcept 的flashObject。
flashObject是一个探测和嵌入Flash的javascript脚本。它能够所有在PC和MAC上的主流Flash插件,为嵌入Flash Movie而设计。它有利于搜索引擎,且能通过HTML验证。
- 下载FlashObject 1.3
- 把flashobject.js加入页面的head标签中
- 具体代码如下:
HTML代码
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab #version=7,0,19,0" width="550" height="400" align="middle" id="foo"> <param name="allowScriptAccess" value="sameDomain" /> <param name="movie" value="foo.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#ffffff" /> <param name="flashvars" value ="variable1=value1&variable2=value2" /> <embed src="foo.swf" quality="high" bgcolor="#ffffff" width="550" height="400" name="foo" align="middle" flashvars="variable1=value1&variable2=value2" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> </object>flashObject代码:
<div id="flashcontent" style="width: 550px; height: 400px"></div> <script type="text/javascript"> var fo = new FlashObject("foo.swf", "foo", "550", "400", "7", "#ffffff"); fo.addParam("allowScriptAccess", "low"); fo.addParam("wmode", "sameDomain"); fo.addParam("quality", "high"); fo.addVariable("variable1", "value1"); fo.addVariable("variable2", "value2"); fo.write("flashcontent"); </script> - 更多内容可以查看flashObject文档。
四、总结
依据微软的技术信息和上述解决方案来看,解决问题的核心法就是实现active控件下载和主页面分离。其主要办法有两个:
- 利用javascript的document.write或innerHTML把下载activeX控件的标签从页面分离出去。
- 利用javascript构造activeX控件下载函数,把需要下载的activeX标签属性写入函数。
采用js和页面分离是最容易实现的办法。但是从长远和易用性角度来看,应用flashObject类似的方法,是一个很好的选择。
Reference:
- [1]Internet Explorer ActiveX 更新
- [2]Activating ActiveX Controls
- [3]Preparing Websites with Active Content for Announced Browser Changes
- [4]FlashObject: Javascript Flash detection and embed script
五、更巧妙的方法[2005.05.29]
今天又发现一种解决方案,;利用原理是一样的,但是解决方案另辟蹊径,显示出非常高的技巧,该方法对原有页面有大量的通过js直接写在主页面上情况提供了非常便捷的解决方案。
使用方法如下:
1、把下面代码放入一个js文件中。
if(typeof(dclk_isDartRichMediaLoaded) == "undefined") { dclk_isDartRichMediaLoaded = true; function dclkWrite(str){ if(dclk_shouldOverride) { dclk_original_documentWrite(str); } else{ document.write(str); } } function dclkWriteln(str){ if(dclk_shouldOverride) { dclk_original_documentWriteLn(str); } else{ document.writeln(str); } } function dclk_isInternetExplorer() { return (navigator.appVersion.indexOf("MSIE") != -1 && navigator.userAgent.indexOf("Opera") < 0); } dclk_shouldOverride = dclk_isInternetExplorer(); if(dclk_shouldOverride) { dclk_original_documentWrite = document.write; dclk_original_documentWriteLn = document.writeln; document.write = dclkWrite; document.writeln = dclkWriteln; } }2、通过js链接方式把改代码链入到主文件的头部即可。
注意,该段代码不能直接写入主文件中,也不能跨域调用。
改代码通过链接嵌入的js函数,实现了document.write&document.writeln方法&主页面的分离,从而实现了需要触发activeX控件的HTML代码&主页面分离,非常的精巧。
此代码不能解决一种情况,就是通过innerHTML属性写入需要触发activeX的HTML代码,不过通过上面解决问题的思路,应该也有合适的方法巧妙的解决。
六、又一个巧妙的解决方案,殊途同归2007.11.14。
if(window.ActiveXObject){ var _FLash_Objects=document.all.tags("object"); for(var i=0;i<_FLash_Objects.length;i++){ var _t_obj=_FLash_Objects[i]; _t_obj.outerHTML=_t_obj.outerHTML; } }ps,来自IEBlog的一个好消息:IE计划从2008年4月起通过升级实现无需点击使用ActiveX控件。
- 下载Adobe提供的必须js文件。该文件包括三个部分:
标签:ActiveX, document.write, Flash, IE, JavaScript, microsoft
作者:秦歌,时间:2006-04-20 2:15,归纳于:Javascript & DOM & AJAX,订阅:RSS 2.0,引用:Trackback

很感谢!太好了!激动!感谢!
“当击以激活此控件”现在也还有.不过现在好像有的程序员故意在广告造成这种情况,很多人都会去点击以激活,结果点了广告
总结的不错!
TO 电脑精品教程网: 不是有些程序员故意这么做,而是被指使这么做,哈哈。