Windows XP Service Pack 2中弹出窗口拦截器的研究(转载)

1 引言
1.1 研究背景
微软公司于2004年8月份正式发布了耗资庞大的Windows XP Service Pack 2(英文版),这不是一次简单的补丁打包升级,而是融入了众多新技术的Windows系统更新。微软声称SP2解决了以往的众多系统漏洞并且大大加强了Windows的安全性。对于Web开发者来说,值得关注的是SP2在IE中加入了Pop-up(弹出窗口拦截)功能,这将影响到世界上绝大部分使用弹出窗口的站点。虽然此前在Netscape等浏览器已加入了此项功能,并且Google以及中国的搜索公司Baidu推出的工具栏中也包含了这个功能,但是对于占据大部分市场份额的IE来说,这次升级是影响重大的。因为占据了浏览器市场80%份额以上的IE,每一个站点都不得不小心奕奕地使用弹出窗口。

1.2 参考资料
1) Microsoft Windows XP Service Pack 2 功能变更  http://www.microsoft.com/china/technet/prodtechnol/winxppro/maintain/sp2chngs.mspx
2) 微调您的 Web 站点以适应 Windows XP Service Pack 2 http://www.microsoft.com/china/MSDN/library/Windev/WindowsXP/USdnwxpxpsp2web.mspx
3) Windows XP Service Pack 2 针对开发人员的培训  http://msdn.microsoft.com/security/productinfo/XPSP2/introduction.aspx
4) MSDN http://msdn.microsoft.com  http://www.microsoft.com/china/msdn/


2 项目概述
2.1 研究目的
研究Windows XP Service Pack 2中IE的Pop-up Blocker特征和原理,找到站点的弹出窗口在IE(SP2)下的解决措施。

2.2 测试环境
Windows XP Professional Version 2002 + Service Pack 2
Internet Explorer 6.0.2900.2180

2.3 项目周期
2004年8月26日-9月20日
40小时左右

3 项目内容
3.1 Windows XP SP 2简介
Windows XP Service Pack 2对操作系统做了许多重大改进增强了个人计算机的安全。它能够通过四个方式来抵御通常的攻击,网络保护,内存保护,增强的电子邮件安全性以及更加安全地浏览Internet。另一方面,Service Pack 2提供了更加方便的系统更新程序。管理员能够更加容易地控制企业网络安全,用户可以方便的使用蓝牙设备。Service Pack 2还包括了DirectX 9和Windows Media Player 9,它们包括了安全,性能和功能的改进。

通过 Windows XP Service Pack 2 (SP2),Microsoft 引入了一组安全技术,这些技术将有助于提高基于 Windows XP 的计算机抵御病毒和蠕虫恶意攻击的能力。这些技术包括:
1) 网络保护
2) 内存保护 
3) 增强的电子邮件安全性
4) 更安全的浏览

3.2 Pop-up Blocker

Windows XP SP2在Internet Explorer中增加了Pop-up Blocker(弹出窗口阻止程序),它可以阻止或屏蔽大部分的弹出窗口。对于由最终用户点击链接打开的窗口不会被影响,另外来自本地网和信任站点域的弹出窗口也不会被阻止。

Pop-up Blocker默认为开启状态,这样可以阻止自动打开和在后台打开的弹出窗口,但是用户点击链接打开的窗口仍然可以正常显示。

启用 Pop-up Blocker
可以使用三种不同的方法启用 Pop-up Blocker。
1) 第一次出现时的提示
在第一个弹出窗口出现之前出现提示,询问用户是否启用 Pop-up Blocker。
2) "工具" 菜单
在 Internet Explorer 中,在 工具 菜单上,点击 屏蔽弹出窗口, 然后点击 阻止弹出窗口.
3) Internet 选项.
在 Internet Explorer 的 工具 菜单上,点击 Internet 选项,点击 隐私 选项卡,然后点击 屏蔽弹出窗口。然后点击选项,对 Pop-up Blocker 加以设置。
 
当一个弹出窗口被屏蔽时:
当一个站点的弹出窗口被屏蔽时,会在状态栏上显示一个通知和播放一个声音,而且将在显示区域上边地址栏下边显示信息栏(您可以不播放声音和显示信息栏,参见后面的高级设置选项)。点击状态栏上的通知,可以看到一个带有如下选项的菜单:
1) 显示被阻止的弹出窗口。重新加载弹出窗口。
2) 允许来自该站点的弹出窗口。将当前站点添加到 "允许" 列表。
3) 阻止弹出窗口。开启或关闭 Pop-up Blocker。
4) 弹出窗口选项。打开 " 弹出窗口管理" 窗口。
 
信息栏则会显示弹出窗口被屏蔽消息并通知用户可以通过点击信息栏允许弹出窗口和其他设置:
1) 显示被阻止的弹出窗口。重新加载弹出窗口。
2) 允许来自该站点的弹出窗口。将当前站点添加到 "允许" 列表。
3) 设置是否阻止弹出窗口和显示信息栏以及更多高级设置。
4) 信息栏帮助。


高级设置选项
信任站点列表
最终用户和IT管理员能够通过将一些网站加入信任站点列表从而允许这些网站的自动弹出窗口。

过滤级别设置和其他选项
三种过滤级别:
 高级:阻止所有的弹出窗口(可以通过按住ALT键点击链接打开窗口)
 中级:阻止大部分自动弹出窗口(默认级别)
 低级:允许安全站点的弹出窗口
其他选项:
 当一个弹出窗口被屏蔽时是否播放一段声音
 当一个弹出窗口被屏蔽时是否显示信息栏

*以下内容除非特别标注,否则都是在Pop-up Blocker的默认设置下。

阻止机理
Pop-up Blocker会屏蔽除了除createPopup()(IE5.5及以上版本支持,参见附录)之外的从脚本自动打开的任何窗口。受此影响的一些常用函数是:window.open(), showModelessDialog(), showModalDialog(), showHelp(), window.external.NavigateAndFind()。

检查方法
在已有的资料中,微软还没有提供可以检测用户是否打开了IE Blocker的功能,只是提供了如何检查窗口是否被阻止的方法。

对于window.open()打开的窗口,当窗口被阻止,那么函数将返回空值。当弹出被阻止时,在使用 window.open() 的返回值来避免脚本错误之前,请始终对该值进行检查。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <title>Popup Tester</title>
   <script language=javascript >
    function openWin()
    {
     var sReturn = window.open("http://www.creative.com");
     if (sReturn == null)
     {
      ErrorLog.innerHTML = "Pop-up blolcked.<br />The window object return <font color=red>" + sReturn + "</font>";
     }
    }
   </script>
 </HEAD>
 <body onload="openWin()">
 <div id="ErrorLog"></div>
 </body>
</HTML>
这个例子显示如何检查函数返回值来判断用window.open()方法打开的弹出窗口是否被阻止。

对于使用showModelessDialog(), showModalDialog(), showHelp()自动打开的窗口,可以通过以下两种方式来处理弹出窗口被阻止的情况:
1 如果浏览器版本是IE 5.0及以上,那么就可以在Javascript代码中使用try/catch结构来处理。如下列代码所示:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <title>Popup Tester - Try/Catch construct</title>
 </HEAD>
 <body onload="openWin()">
  <form id="Form1" method="post" runat="server">
   <div id="ErrorLog"></div>
  </form>
 </body>
 
 <script language=javascript >
 function openWin()
 {
  try
  {
   window.showModalDialog("www.creative.com");
  }
  catch (e)
  {
   ErrorLog.innerHTML = "Pop-up blocked.<br />";
   ErrorLog.innerHTML += "Error number: " + e.number;
  }
 }
 </script>
</HTML>
在此例中,当页面初始化时通过openWin()函数自动打开的窗口将被阻止,并显示错误信息和错误代号。

2 让打开窗口的函数设置Javascript错误句柄。如下所示:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <title>onerror Event</title>
 </HEAD>
 <body onload="showPopup()">
  <div id="ErrorLog"></div>
 </body>
 
 <script language=javascript >
 function handlePopupErrors(sMsg, sUrl, sLine)
 {
  ErrorLog.innerHTML = "<b>An error was thrown and caught.</b><p>";
  ErrorLog.innerHTML += "Error: " + sMsg + "<br>";
  ErrorLog.innerHTML += "Line: " + sLine + "<br>";
  ErrorLog.innerHTML += "URL: " + sUrl + "<br>";
  return false;
 }
 function showPopup()
 {
  window.onerror = handlePopupErrors;
  window.showHelp("http://www.creative.com","");
 }
 </script>
</HTML>
这个示例证明了通过设置错误句柄来捕获窗口被阻止时的异常信息。和以上方法一样,可以通过这种方式来通知用户禁用Pop-up Blocker或将站点加入可信站点域来查看弹出内容。

一些不适当的措施
1) 根据弹出窗口被阻止而重定向或关闭窗口
当站点弹出窗口被阻止而重定向时,对于用户来说,就无法通过信息栏来访问弹出的内容。
同样,如果某个窗口由于阻止弹出而关闭,用户也无法看到信息栏。

2) 从弹出窗口中启动弹出窗口
Pop-up Blocker会阻止任何自动弹出的窗口,即便是从弹出窗口中启动新的自动弹出窗口。

3) 不要自动启动setHomePage()对话框
同弹出窗口一样,自动启动的setHomePage()提示将被阻止。

4) 异步请求信息时,站点不要打开新窗口
如果站点在异步请求信息后打开特定的窗口,则 Internet Explorer 可能会阻止这些窗口,即使用户单击了链接以打开该窗口。

5) 不要从ActiveX控件或其它对象启动弹出窗口
对于其他弹出窗口,如果窗口不是从用户操作启动的,那么弹出阻止程序就会阻止它。一个窗口必须响应直接用户操作才允许被打开。

一般的弹出建议
1) 请不要在弹出窗口失败时进行重定向。
2) 如果弹出窗口、下载或 ActiveX 控件被阻止,请不要关闭或自动重定向浏览器窗口。如果您关闭或重定向浏览器窗口,用户将无法在"信息栏"上单击并接受弹出窗口、下载或 ActiveX 控件。
3) 请不要从弹出窗口中启动弹出窗口。
4) 请不要从一个用户操作启动多个弹出窗口。
5) 请不要从 showModelessDialog() 或 showModalDialog() 调用中启动自动弹出窗口。

3.3 弹出窗口限制
请不要设置脚本使弹出窗口的标题栏,地址栏或状态栏离开屏幕可视区域之外。Service Pack 2会对使用window.open() 或 window.createPopup() 方法弹出的窗口进行限制,来确保窗口的全部信息可见。

1 对于使用 window.open() 打开的窗口,请保证状态栏能够显示,并且窗口不要覆盖任务栏。如果弹出窗口的位置在屏幕之外,窗口限制措施会调整窗口的X和Y坐标,使它完全显示在屏幕中。另外,现在,带有 fullscreen=yes 的 window.open() 会导致最大化的窗口,而不是 kiosk 模式的窗口。无论弹出窗口的宽度和高度被设置为多少,它都会被限制在屏幕中。

注:kiosk模式是一种未显示任何浏览器控制项(如工具栏)的Web浏览器模式
 
如上图所示,通过window.open()打开的弹出窗口可能会覆盖任务栏或是父窗口,因此,请确保正确设计弹出窗口。

2 对于使用 window.createPopup() 打开的窗口将不会覆盖父窗口的标题栏或状态栏,因此即使窗口的高度被设置为超过父窗口或屏幕大小,SP2依然会限制它保证父窗口的标题栏或状态栏。另外,如果用户没有最大化父窗口,当父窗口位于屏幕的不同位置时,弹出窗口可能会在父窗口之外甚至部分或全部在屏幕之外。
 
在上图中,通过window.createPopup() 打开的窗口(蓝色边框,红色背景的部分)在脚本中被设置为宽1400,高900,但显示时,弹出窗口被限制了高度来保证父窗口的标题栏或任务栏,而它的宽度则不受影响。
 
 
上两图则说明了当非最大化状态的父窗口处于屏幕的不同位置时,弹出窗口可能出现的情况。

无论是哪种脚本打开的窗口,在设计时都需要考虑UI元素如显示主题、字体大小和分辨率等来调整窗口的显示。

3.4 如何检测浏览站点的浏览器是否是SP2 中的 Internet Explorer
可以使用 window.navigator.userAgent 来检测。
var g_fIsSP2 = false;
function browserVersion()
{
   g_fIsSP2 = (window.navigator.userAgent.indexOf("SV1") != -1);
   if (g_fIsSP2)
   {
   //This browser is Internet Explorer in SP2.
   }
   else
   {
   //This browser is not Internet Explorer in SP2.
   }
}

如果用户代理字符串中包含"SV1",说明连接到您站点的浏览器是 SP2 中的 Internet Explorer。

3.5 其它方面
Windows XP Service Pack 2(SP2)还对ActiveX控件的安装和下载文件产生影响。

在SP2中,ActiveX 控件的模式安装会被信息栏阻止并提示该站点要求安装控件。用户可以通过点击信息栏来安装ActiveX控件。对于使用弹出窗口和HTML对话框来安装 ActiveX 控件也会被阻止。

在没有经过用户点击或按键来启动的文件下载提示也会被信息栏阻止。

4 结论
Windows Service Pack 2中,Pop-up Blocker会阻止除了createPopup()之外的大部分脚本自动弹出的窗口。可以通过函数的返回值来判断弹出窗口是否被阻止,并采取进一步的措施。


附录:

CreatePopup() Method

Internet Explorer 5.5 支持window对象的一个新方法,createPopup()。你可以通过下面的方式创建一个弹出窗口:

var popupObj = window.createPopup();
当你创建了这个对象时窗口不会被显示,必须调用它的方法:

popupObj.show(yOffset, xOffset, width, height, referenceObj)
其中:

yOffset 是距离屏幕左上角的水平坐标偏移。
xOffset 是距离屏幕右上角的水平坐标偏移。
width 是弹出窗口的宽度。
height 是弹出窗口的高度。
referenceObj  是一个替代屏幕左上角位置的参数,通过设置它你可以定义 yOffset 和 xOffset 相对于它的位置。

下面是一个定义了背景和边框的弹出窗口示例:

<SCRIPT LANGUAGE="JavaScript">
<!--
var oPopup = window.createPopup();
var oPopupBody = oPopup.document.body;
oPopupBody.style.backgroundColor = "magenta";
oPopupBody.style.border = "solid blue 3px";
oPopupBody.innerHTML = "Click outside <B>popup</B> to close.";
oPopup.show(300, 80, 200, 50, document.body);
// -->
</SCRIPT>

MSDN上关于createPopup()的参考文档:http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/createpopup.asp

posted on 2005-10-27 16:30  IORICC  阅读(1638)  评论(1编辑  收藏  举报