SharePoint Server 2007 的一个问题

在用 Deep Zoom Composer 生成内容后,传到 SharePoint Server 2007 中后,发现不能浏览,仔细检查发现 Deep Zoom Composer 生成的很多以 _files 的目录,传到 SharePoint Server 2007 中后,目录被改了名字,自动在最后加了下划线 “_”,导致不能正常访问。

此处详细介绍了此问题。

 

在 GridView 中增加记录的方法

在 ASP.NET 2.0 中,GridView 支持修改/删除记录,但却不支持新增记录的功能(个人感觉是 GridVew 的一大缺憾,估计在下一版本中会加入此功能),大多数人建议用 FormView 来完成增加记录的功能,但是 FormView 和 GridView 不是同一个表格,所以无法在同一个页面的同一个表格中显示。如果故意将 FormView 或自己的一堆于用新增功能的控件使用普通的表格组装起来,那么会碰到一个很麻烦的问题,即两个表格的列宽如何协调一致,大多数情况下,大家在做表格的时候,表格中各列的宽度都是自动调整的,所以强行指定宽度在很多情况下并不适用。

通过实践,想出了一种办法,主要步骤如下所示:

1) 在 GridView 的 EmptyDataView 中,放置一个普通的Html Table,以便在GridView绑定的数据源中无数据时依旧显示表头(如果数据源为返回的数据行数为0,GridView默认是不显示表头的),假设 ID 为 tbHeader,它的作用是下面用于新增功能的 tbForm 的各列控件提供说明(充当表头);

2)在 GridView 下面,放置一个普通的 HTML 表格,其列数和 GridView 中定义的列数保持一致,但行数只有一行,然后在此表格的各列中放入用于新增功能的各个控件(如 TextBox等),假设此表格的 ID 为 tbForm

3)在页面中加入一段客户端脚本,以便使页面展示到客户端时,利用 Javascript 将两个表格强行合并到一起,这样就可以将只有一行的 tbForm 合并到 GridView中,因此 GridView 的最下面多出一行,其中有 tbForm 表格中定义的输入控件和“添加”链接(按钮),主要代码(JavaScript)如下:

function MergeTable(source,dest)
{
    var row;
    var cell;
    var sourceTb = document.all(source);
    var destTb = document.all(dest);
    for (var i=0; i<sourceTb.rows.length; i++)
   {
         row = document.createElement(“TR”);
         for (var j=0; j<sourcetb.ROWS(I).CELLS.LENGTH; j++)
<sourceTb.rows(i).cells.length; j++)
        {
             cell = document.createElement(“TD”);
             row.appendChild(cell);
             //复制对象
             for(k=0;k<sourceTb.rows(i).cells(j).all.length;k++)
                 cell.appendChild(sourceTb.rows(i).cells(j).all.item(k));
        }
        destTb.tBodies(0).appendChild(row);
    }
    for (var i=sourceTb.rows.length-1; i>=0; i–)
    {
        sourceTb.deleteRow(i)
    }
}

function ChangeTableLayout()
{
     if(document.all(‘tbHeader’) == null)
        MergeTable(‘tbForm’,”);
    else
        MergeTable(‘tbForm’,’tbHeader’);
}

ChangeTableLayout();

如果 GridView 绑定时没有数据,将不显示其中定义的各列,而只显示 EmptyDataView 中的 tbHeader,这时要合并 tbHeader 和 tbForm。如果 GridView 绑定时包含数据,则不会显示 EmptyDataView(当然也不会显示其中的 tbHeader),但这时会显示 GridView 中定义的各个列,因此只需将 GridView 本身和 tbForm 合并即可。 GridView 的客户端ID可以用GridView.ClientID来获取。

在服务器端很容易知道 GridView 绑定后是否包含数据,但对于客户端来说,不容易检查,一个简单的作法就是检查页面中有没有 tbHeader 对象(如果有,则说明表格没有数据,如果无此对象,表示 GridView 中包含数据… 好啰嗦)

4)如果是 AJAX 环境,上述脚本有可能不被执行,可以调用 Sys.Application.load.add ( JavaScriptFunction) 来强制执行脚本,来合并表格,主要代码如下(C#):

ScriptManager myScriptManager = ScriptManager.GetCurrent(Page);
if (myScriptManager.IsInPartialRenderingMode)
{
    Page.ClientScript.RegisterStartupScript(this.GetType(), “ShowFullTable1”, “ChangeTableLayout();\n”, true);
}
else
{
    Page.ClientScript.RegisterStartupScript(this.GetType(), “ShowFullTable2”, “Sys.Application.load.add (ChangeTableLayout);\n”, true);
}

注:上述代码中的 ChangeTableLayout 为客户端脚本函数的名称,其中调用第3步骤中的代码,上述代码在 Atlas 中通过,在 ASP.NET AJAX Beta 上尚末测试。

另:为了更能说明上文代码的效果,我抓了一个截图,图中包括表头在内的前三行就是 GridView,最下面一行其实来自于另一个表格,在客户端强制合并后,显示效果就是这样,看起来象是一个表格。

感谢大家的意见,我对原文中的表述不明确的地方进行了更改。

ASP.NET 中处理页面“回退”的方法

我们在编写基于 ASP.NET 的应用程序时,如果代码执行出错或检测到异常,一般会提示用户“返回”或“回退”,或者在多步操作、列表/详细的查看界面中,也会给用户提供回退到上一页面的链接,对于这种情况,大家很快就会想到的简单做法就是利用 Javascript 来实现,即 history.go(-1) ,但是由于 ASP.NET 页面的 PostBack 机制,所以 history.go(-1) 可能还是当前页面,而不能真正回退到上一页面。

在 Classifieds Site Starter Kit 中,学习到一种不错的关于回退的处理方法,可以分别在客户端和服务器控件中实现页面的回退,代码如下:

1)首先在页面中增加两个属性

//记录上一个页面的信息
private string UrlReferrer ...{ get ...{ return ViewState["UrlReferrer"] as string; } set ...{ ViewState["UrlReferrer"] = value; } } //记录 PostBack 的次数 public int NumPostBacks ...{ get ...{ if (ViewState["NumPostBacks"] != null) return (int)ViewState["NumPostBacks"]; else ...{ ViewState["NumPostBacks"] = 0; return 0; } } set ...{ ViewState["NumPostBacks"] = value; } }
 

2)在 Page_Load 事件记录上一页面地址、更新 Postback 次数、设置回退链接的地址

// 记录上一页面的信息或更新 PostBack 的次数 protected void Page_Load(object sender, EventArgs e) ...{ if (!Page.IsPostBack) ...{ if (Request.UrlReferrer != null) this.UrlReferrer = Request.UrlReferrer.ToString(); } else NumPostBacks++; int goBackSteps = NumPostBacks + 1; BackLink.NavigateUrl = String.Format("javascript:history.go(-{0});", goBackSteps); }

 

3)直接在代码中处理回退操作(如 Back_Click),可以直接调用如下方法

//在代码中回退 protected void ReturnToPreviousPage() ...{ string referrer = UrlReferrer; if (referrer != null) Response.Redirect(referrer); else Response.Redirect("~/default.aspx", true); }

利用 AOP 实现 .NET 上完整的基于角色的访问控制(RBAC)模型

近期帮别人在 ASP.NET 中实现简捷的安全/权限控制,于是进行了相关研究与内容搜集,并整理成代码,已在实际的项目中运用,效果突出,比 .NET 中的代码访问安全性(CAS)和 ASP.NET 中的相关安全控制机制更为灵活。

于是把其中实现的内容和主要代码共享出来,但内容较多,放在在随笔里会干扰大家查看首页的视线,所以归到文章里,感兴趣者可以在这里http://blog.joycode.com/moslem/articles/85194.aspx)查看。

本文及其中的代码主要介绍了以下内容:

  • 如何在 C# 中简捷/方便地进行 AOP 编程
  • 如何利用 AOP 来透明地在业务逻辑对象中进行权限检查
  • 如何实现完整的基于角色的访问控制模型
  • 如何在UI上针对不同的用户权限对控件进行设置(如禁止或隐藏)
  • 如何设置 Attribute,如何利用反射获取程序集中所有的、指定类型的 Attribute 定义
  • 其他相关内容

一组 ASP.NET 2.0 主题文件下载

在 ASP.NET 2.0 中,大多数控件都可以直接“自动套用格式”,以便设置一些内置的配色方案,能够方便地设计多姿多彩、色彩丰富的页面,除些之外,ASP.NET 2.0 还提供了网站和页面的主题(Theme)和Skin的功能,可以在网页或网站层次设定各种控件的显示风格,以便统一站点的外观。

在实际开发中,实际上大家可能不会过多地采用内置的“自动套用格式”的功能,而是自己来设定控件的色彩、字体等,当然也有可能是通过 Theme/Skin 来进行的,但是,以我的实践来看,实现机制是很好,但结果往往另人不满意,主要原因是缺乏色彩方面的感觉,往往会设计出来色彩冲突、不协调,甚至在很多情况下相当不好看的界面 …

即然有这么好的实现机制,肯定会有人实现/共享很好的 Theme/Skin ,Google 了一下,找到一组 Theme,看起来还是相当不错的,可以直接应用的项目开发中,当然了,这组 Theme 也有一些小瑕疵,即某些对比色的过于接近而比较模糊。

 Theme预览:http://www.dotnettreats.com/SampleThemes/Default.aspx
 Theme下载:http://www.dotnettreats.com/tools/Default.aspx

在 ASP.NET 上实现锁定表头、支持滚动的表格的做法

首先看看 CodeProject 上的两个东西

1、The Freeze Pane DataGridhttp://www.codeproject.com/aspnet/FreezePaneDatagrid.asp

利用文章中提到做法及代码,可以实现在 ASP.NET 1.1 上的、支持横向滚动与纵向滚动的表格,基本上是使用 CSS 实现的,比较简单。

在 ASP.NET 2.0 上,由于文档 HTML DOCKTYPE 发生了变化(HTML->XHTML),所以在使用原文中的横向滚动条会出现问题,但是使用纵向滚动条和锁定表头没有问题。

这种做法没有考虑页面 PostBack 时记录表格的滚动位置,使得用户不得不重新去寻找刚才选中/编辑的那条记录,这比较的不人性化。

2、ScrollingGrid: A cross-browser freeze-header two-way scrolling DataGridhttp://www.codeproject.com/aspnet/ScrollingGrid.asp

此文章利用 Panel 控件和 DataGrid 控件实现了 ASP.NET 1.1 下的完整的、可实现双向滚动、表头锁定的表格,而且它实现了可以记录表格的滚动位置,页面 PostBack 后,表格仍能自动滚动到原有位置。这个控件的一个最大优点是能够适应多种浏览器,如 Internet Explorer 、FireFox 等。

在 ASP.NET 平台上,由于 DataGrid 控件已经升级为 GridView ,所以此控件已不能使用,按照文章下面的讨论,作者声称会尽快升级控件,但似乎在实现时碰到一些麻烦(如何确实表头各列的宽度),目前还没有结果。

目前我的做法:

  1. 参照文章1中提到的作法,利用 CSS 来实现锁定表头的功能
  2. 利用 Panel 控件,设置 ScrollBar 为 Vertical,再在其中放入 GridView 控件 ,可以实现竖向滚动条的功能
  3. 利用 Atlas ,将上述 Panel 再放入 UpdatePanel ,以透明实现保持滚动条位置的功能

示例代码:

<h1>滚动条表格演示h1> <style type="text/css">...... th {...}{...}{...}{ border-right: 1px solid silver; position:relative; top: expression(this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.scrollTop-2); /**//**//**//*IE5+ only*/ } style> <atlas:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="True"> atlas:ScriptManager> <br /> <asp:Panel ID="GridPanel" runat="server" Height="250px" ScrollBars="Auto" Width="562px"> <atlas:UpdatePanel ID="UpdatePanel1" runat="server"> <ContentTemplate> <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1" SkinID="GridView" Width="434px"> </asp:GridView> </ContentTemplate> </atlas:UpdatePanel> </asp:Panel>

这样能基本上实现一个能够锁定表头、竖向滚动、能够在页面PostBack时保持滚动位置的表格,能够满足大部分应用需要。

ASP.NET 2.0 中 AuthorizationStoreRoleProvider 可用性不高

一、授权管理概述

一般在应用程序中,比较理想、完整的授权模式就是基于角色的授权(Role Based Access Control-RBAC),它的主要目标是实现了用户与安全操作的分离,而在中间加入了角色的隔离层,从而实现了灵活性和可扩展性,具体来说,主要是这种方式:

  1. 在编写程序的时候,定义出程序的功能(或称为安全操作,如 AddBook, ModifyBook …)
  2. 在应用程序部署的时候,按照业务安全策略的要求,定义角色(如 BookManager),并定义角色与功能的对应关系
  3. 在应用程序运行期,定义可以使用系统的用户(如张三、李四),然后定义用户与角色的关系

这样通过“三个实体,两个对应”,就能找到用户和功能的关系(即用户能否执行此功能)。

二、ASP.NET 2.0 中的授权管理功能

ASP.NET 2.0中,提供了三种授权管理的提供者,分别为:AspNetSqlRoleProvider、AuthorizationStoreRoleProvider、AspNetWindowsTokenRoleProvider。

默认 AspNetSqlRoleProvider 只能提供角色与用户的实体及其对应关系,缺乏功能层次的定义和关系,所以仅能适用于有限场合,如基于 URL 的授权,或者在程序中手动使用 Roles API(Roles.IsUserInRole)来判断当前用户是否具有授权,但是这种方式的前提是角色是 Hard Code(硬编码的),以后如果角色所允许的功能发生了变化,只能通过修改程序来实现。

再来看看 Windows 2003 中附带的授权管理器(Authorization Manager,以下简称 AzMan),不可否认,它的设计比较完整地体现了 RBAC的思想,即首先定义操作,然后把操作归类形成任务(大任务也可以包括子任务),可以定义角色,然后在角色中定义其可以执行的任务或操作(大角色也可以包含小角色),最后可以应用程序中分配用户、建立角色与用户的对应关系,同时,AzMan 还提供业务规则检查的功能,即可以在任务级别定义脚本,对是否授权进行进一步的细粒度的检查,表面上看,还是比较圆满的。

但是 AzMan 的一个重大限制就是只支持 Windows 用户,它要求用户的标识为 SID(如S-1-5-21-XXXX-XXX)的格式。虽然我们可以使用 AzMan 的 API ,如 InitializeClientContextFromStringSid 来构造一个虚拟的 SID (例如,在我们的应用程序中,我们用户的 ID 为一个自增量的整数 Y,那就可以虚拟成 S-1-5-21-Y的方式)这样我们就可以利用 AzMan API 来绕开只允许Windows 用户的限制,但这些工作全部要手工完成,纯体力活,得不偿失。

本来以为 ASP.NET 2.0 的AuthorizationStoreRoleProvider 做为默认的三种 RoleProvider 之一,能为我们提供这些方面的便利功能,但在
使用之后才发现,限制依然存在,实用性仍然不够:

  1. 在定义角色时,它会把角色定义在 AzMan的“角色分配”结点上,而不是“角色定义”结点上,有点奇怪
  2. 如果使用 AspNetSqlMembershipProvider ,那么在为用户分配角色时,就会引发“帐户名与安全标识间无任何映射完成”的错误,这可以看出来 AzMan 依然是使用 Windows 用户,这一个限制很是致命,也就是说
    AspNetSqlMembershipProvider 和 AuthorizationStoreRoleProvider 是不能共用的

如果能够把 AspNetSqlMembershipProvider 中用户的 MemberId (GUID类型,格式为“XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX”)转换成 SID (S-R-I-S-S)还有可能通过 AzMan API 来利用AzMan ,但这不是通过 AuthorizationStoreRoleProvider 来进行的,而且目前我也没有找到好的、能够双向转换的方法。

三、一种实用的授权管理机制设想

目前临时想到一种即能完整实现 RBAC,又能利用 RoleProvider 的解决办法是:

  1. 利用 AspNetSqlRoleProvider 来管理 Role、定义 Role 与AspNetSqlMembershipProvider 中用户之间的关系
  2. 新增一自定义XML文件,在其中定义任务/操作列表,在编写程序时,可以在类或方法的属性中指定操作名称
  3. 同时在上述XML文件中定义 Role 与操作的对应(包含)关系
  4. 在程序中利用公用程序来检查权限,这无需写死(Hard Code)任何东西,因为是直接从当前类/方法中取出操作名称,再直接获得当前用户名,再检查第 2、3步的XML 文件文件即可。

一些关于Visual Studio 2005 代码段(Code Snippet)的信息

非常喜欢Visaul Studio 2005 中的代码段,大大节省了一些无聊的、没有技术含量的代码编写工作,如实体类的属性设置等。

Visual Studio 2005 中的 VB.NET 的代码段比 Visual C# 的多出不少,是不是吸引开发人员?

我们可以修改系统中现有的 snippet 文件(C:\Program Files\Microsoft Visual Studio 8\VC#\Snippets\2052\Visual C#目录),来增加自己常用的 snippet。

网上(http://www.gotcodesnippets.net/)也有不少别人编写的 snippet ,可以按需取用。

要想共享或发布 snippet,最好做成Visual Studio 支持的格式 vsi ,其实是就是一个 更改了后缀名的 zip 文件,里面包含一个 XML 描述文件、一个或多个 snippet 文件(可以从上面网站中获得一个 vsi 文件来参考如何制作过程)。 

在 Visual Studio 2005 中,插入代码段的快捷键是 Ctrl K + Ctrl X ,代码段管理器的快捷窗口是 Ctrl K + Ctrl B。

这里提供一个比较好用的 Public Property 的 Snippet ,是对 http://www.gotcodesnippets.net 上拿到 Public Property 稍加修改之后形成的东西,这个我最常用 🙂 。

<?xml version="1.0" encoding="utf-8"?> <CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet"> <CodeSnippet Format="1.0.0"> <Header> <Title>Public Property</Title> <Shortcut>pp</Shortcut> <Description>公共属性</Description> <Author>LiYanZhi ([email protected]_</Author> <SnippetTypes> <SnippetType>Expansion</SnippetType> </SnippetTypes> </Header> <Snippet> <Declarations> <Literal> <ID>accessor</ID> <ToolTip>The access modifier</ToolTip> <Default>public</Default> </Literal> <Literal> <ID>type</ID> <ToolTip>属性类型</ToolTip> <Default>string</Default> </Literal> <Literal> <ID>name</ID> <ToolTip>属性名称</ToolTip> <Default>MyProperty</Default> </Literal> </Declarations> <Code Language="csharp"> <![CDATA[private $type$ _$name$; $accessor$ $type$ $name$ { get { return _$name$; } set { _$name$ = value; } }$end$]]> </Code> </Snippet> </CodeSnippet> </CodeSnippets>

在修改 Snippet 时,也发现其中的一些不足,比如表达式中函数支持太少,例如上例中,一般用 _name 表示内部字段,用 Name 表示属性,但缺乏第一个字母大小写转换的函数。

对系统管理员或许有用的两个 VBScript

function act1(no)
{
if(document.all.item(“y”+no).style.display==””) document.all.item(“y”+no).style.display=”none”;
else document.all.item(“y”+no).style.display=””;
}

1、在 Windows 或 AD 中批量增加用户

使用方法,新建一 users.csv,字段格式必须按如下顺序,且不能为空: 登录名, 姓名, 密码,  描述;然后将脚本与 CSV 文件存储至同一目录,以管理员/域管理员运行脚本即可。

代码>>  (单击显示/隐藏)

'// Name: BulkAddUser
'// Purpose: 从 CSV 文件中批量生成 Active Directory 用户 '// 注意: '// 1. 源文件必须使用逗号分割 '// 2. 字段必须按如下顺序,且不能为空: 登录名, 姓名, 密码, 描述 '// 3. 只能由域管理员才能运行此程序 Option Explicit Dim oFSO, oTF, objRootDSE, objContainer, i Dim aLine, sLine, sLogon, sPass Dim sLoginName, sDisplayName, sDescription '// 用户批量文件 Const InpFile = "users.csv" Const ForReading = 1 Set oFSO = CreateObject("Scripting.FileSystemObject") Set oTF = oFSO.OpenTextFile(InpFile, ForReading, True) Set objRootDSE = GetObject("LDAP://rootDSE") Set objContainer = GetObject("LDAP://cn=Users," & objRootDSE.Get("defaultNamingContext")) i = 1 Do While oTF.AtEndOfStream <> True sLine = oTF.ReadLine aLine = Split(sLine, ",", -1, 1) sLoginName = aLine(0) sDisplayName = aLine(1) sPass = aLine(2) sDescription = aLine(3) If IsEmpty(sLoginName) Or IsEmpty(sDisplayName) Then MsgBox "" & i & " 行数据有误:登录名和姓名不能为空", vbExclamation, "Add Bulk Users" End If Set objLeaf = objContainer.Create("User", "cn=" & sLoginName) objLeaf.Put "sAMAccountName", LCase(sLoginName) objLeaf.Put "givenName", Left(sDisplayName, 1) objLeaf.Put "sn", Mid(sDisplayName, 2) objLeaf.Put "UserPrincipalName", LCase(sLogon) objLeaf.Put "DisplayName", sDisplayName objLeaf.Put "description", sDescription objLeaf.SetInfo '// 是否重复 If Err.Number = -2147019886 Then MsgBox "User logon for " & sLogon & " already exists.", vbExclamation, "Bulk Add Users" Else '// Set initial password objLeaf.setpassword sPass objLeaf.AccountDisabled = False objLeaf.SetInfo End If i = i + 1 Loop MsgBox "用户创建完毕.", vbInformation, "Bulk Add Users"
Set oTF = Nothing
Set oFSO = Nothing

2、清理 IIS Log 中的非重要信息(如 XML、JS、JPG、GIF等资源的访问日志),只留下 asp 和 aspx 的访问日志。经我在一台服务器上测试,日志文件由 6G 变为 900M ,大大节省了空间。

使用方法:保存代码至 .vbs 文件,确认其中关于 IIS 日志路径是否正确,然后运行即可。

代码>>  (单击显示/隐藏)

<span id=y2 style="DISPLAY: none" color="#0000ff" face="Courier New"

Const ForReading = 1 Const ForWriting = 2 Dim tempLine,curDir,objFolder,objFSO,objFiles,objFile,f curDir = "C:\Windows\System32\LogFiles\" Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFolder = objFSO.GetFolder(curDir) Set objFiles = objFolder.Files For Each f in objFiles If Instr(f.Name,"ex0") > 0 Then Set objFile = objFSO.OpenTextFile(curDir + f.Name, ForReading) Set objFile1 = objFSO.OpenTextFile(curDir + Replace(f.Name,"ex0","bk0"), ForWriting, True) Do Until objFile.AtEndOfStream tempLine = objFile.ReadLine If Instr(tempLine,".asp - 80") > 0 OR Instr(tempLine,".aspx - 80") > 0 Then objFile1.WriteLine tempLine End If Loop objFile.Close objFile1.Close End If Next Msgbox "日志文件清理完毕"

IIS 的一个不足和一个使用建议

经常借用别人公司的一台托管的服务器上传下载些资料,顺便也帮人盯着服务器的配置与安全,前两天发现,系统盘 10G 硬盘空间没剩多少了,进去一看,原来 IIS 的日志文件(%windir%\system32\logfiles)下有5-6个G的日志文件,每天的日志约有 30-40M,于是把这些日志文件备份出来,压缩存储了一下,立刻节省了大量磁盘空间出来。

这个网站的访问里并不大,但日志文件为什么这么大呢,打开一看,IIS 的日志记录是很详细完整,但是仔细一看,好多行信息都是 jpg 和 gif ,这可能由于这台服务器是公司/产品宣传的缘故,所以图像文件较多,因此当访问一个页面时,会记录 10-20 条日志信息,从日志的真正用处来看,这些多余的图像文件的访问日志并不需要,而且,这么多的日志信息显然消耗了服务器的计算、IO、存储资源,影响高并发时的性能。

于是想在 IIS 的日志里对记录的 URI 资源类型做一下限制,很遗憾,没有发现这样的选项,在 Google 上似乎也没有找到替代的做法,这样看来,这好象是 IIS 日志记录功能的一个不足之处。

更新:感谢思归提供的解决办法,我把 Images 目录的日志记录取消了之后,日志文件在大小见下图:

另外再次极力推荐一下 IIS 的 gzip 功能,最近一直在研究其对性能和带宽的影响,应该来说,对于绝大多数互联网上的服务器来说,CPU 的资源比带宽资源的利用率更低,因此应该利用这些闲置的 CPU 资源来压缩页面,降低带宽点用,提高响应速度,而且,对于静态内容来说,这种压缩可以生成临时文件,避免每次访问都对资源进行压缩,因此对 CPU 资源的影响也是非常小的。对于大型企业来说,要在集中位置部署一个 B/S 的系统,那么利用 gzip 能大大节省租用运营商通讯线路带来的成本(利用 Internet Security and Accelerator 提供的 HTTP 压缩和缓存功能,也可以达到同样的目的)

port80software 这个网站上,提供了一在线测试工具,可能对你的网站进行测试,以确定其是否提供 gzip 压缩以及压缩比重、传输速度的提升等。