当在IIS7上使用MVC3时,我该如何启用gzip压缩?

103

有人知道如何在MVC 3中启用gzip压缩吗?我正在使用IIS7。

Google Chrome审核结果:

  1. 启用gzip压缩(4)
  2. 使用gzip压缩以下资源可以将它们的传输大小减少约三分之二(~92.23KB):
  3. /mydomain/ 可以节省 ~1.53KB
  4. jquery-1.4.4.min.js 可以节省 ~51.35KB
  5. Cufon.js 可以节省 ~11.89KB
  6. Futura.js 可以节省 ~27.46KB

并非完全重复:https://dev59.com/x3RB5IYBdhLWcg3wr44U - jpaugh
3个回答

144

您可以通过以下方式通过您的web.config文件配置压缩:

<system.webServer>
    <urlCompression doStaticCompression="true" doDynamicCompression="true" />
</system.webServer>

您可以在iis.net/ConfigReference找到此配置元素的文档。这相当于:

  1. 打开Internet Information Services (IIS管理器)
  2. 通过左侧的树视图导航,直到您到达要修改的虚拟目录
  3. 选择适当的虚拟目录,以使右侧窗格的标题成为该虚拟目录的名称。
  4. 在右侧窗格中选择 "IIS" 下的 "Compression"
  5. 选中两个选项,在最右侧的 "操作" 下选择 "应用"。

注意: (如评论中所指出) 您需要确保已安装 Http 动态压缩,否则设置 doDynamicCompression="true" 将没有任何效果。最快的方法是:

  1. 开始 > 输入 optionalfeatures (这是访问“打开或关闭Windows功能”窗口的最快方式)
  2. 在“Windows 功能”树视图中导航到 Internet Information Services > World Wide Web Services > 性能特征
  3. 确保选中了 "动态内容压缩"
  4. 单击 "确定" 并等待 Windows 安装组件

11
需要注意的是,您需要安装Http Compression Dynamic IIS选项才能使其正常工作。此答案中的配置参考链接包含详细信息。 - Caleb Vear
17
在 Windows Server 2008 中,optionalfeatures 命令对我无效。相反,需要导航到“服务器管理器” > “角色” > 滚动到“Web 服务器(IIS)”> 点击“添加角色服务”。现在请确保已安装“Web 服务器”>“性能”>“静态内容压缩”和“动态内容压缩”。 - Rory
1
请注意,这可能会破坏您的“Vary:”主机头。更多信息:https://dev59.com/RlXTa4cB1Zd3GeqP1WiB#20646735?noredirect=1#20646735 - jjxtra
2
至少在我的经验中,这个压缩除了MVC控制器的输出之外的所有内容。由于某种原因,它们返回没有任何gzip压缩的HTML。 - Chris Moschini
1
注意!!!IIS动态压缩会剥离Vary头,这可能是一个错误或特性,我不确定,但如果您想要缓存正常工作,实现自定义过滤器更有意义。 - Akash Kava
显示剩余4条评论

33

如果你愿意的话,可以通过编程来实现这一点。我会创建一个基础控制器,每个控件都继承自该控制器,并用下面的属性进行装饰。

public class CompressAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

        var encodingsAccepted = filterContext.HttpContext.Request.Headers["Accept-Encoding"];
        if (string.IsNullOrEmpty(encodingsAccepted)) return;

        encodingsAccepted = encodingsAccepted.ToLowerInvariant();
        var response = filterContext.HttpContext.Response;

        if (encodingsAccepted.Contains("deflate"))
        {
            response.AppendHeader("Content-encoding", "deflate");
            response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
        }
        else if (encodingsAccepted.Contains("gzip"))
        {
            response.AppendHeader("Content-encoding", "gzip");
            response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
        }
    }
}

2
@JustAnotherUserYouMayKnow - 这取决于您如何提供资源;如果您直接指向服务器上的文件,则不行,但是如果通过操作(如我们的资源管理系统)来提供它们,则效果非常好。顺便说一句,Rick Strahl已经更新了这个功能,以支持在压缩之前检查客户端是否实际支持gzip。链接 - Paul Carroll
4
请注意,在重定向时保护“filter”为空是很重要的。我使用了“var response = ...;if( response == null || response.Filter == null)return;”来进行保护。 - Travis J
2
此外,您可能希望先使用 gzip ,而不是 deflate ,在这里阅读更多信息:https://dev59.com/zXRC5IYBdhLWcg3wK9yV#9856879 - Travis J
IIS会缓存压缩文件,以便提高性能时无需再次压缩。如果可以,请使用IIS,并仅在无法使用IIS压缩时使用此方法。 - Muhammad Rehan Saeed
1
这些解决方案都无法在MVC5、IIS 8.5、.Net 4.5 Localhost上运行。我该怎么办?有什么建议吗? - aadi1295

12

压缩功能在服务器级别上启用/禁用。请参见 IIS 管理控制台中的 IIS 压缩模块。

以下是来自 Microsoft 网站的 IIS 操作说明


1
你也可以在 web.config 中进行设置。 - Jack Marchetti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接