在ASP中可以选择性地禁用gzip压缩吗?NET/IIS 7

本文关键字:压缩 NET IIS gzip ASP 选择性 | 更新日期: 2023-09-27 17:50:13

我正在使用一个长期存在的异步HTTP连接,通过AJAX向客户机发送进度更新。当启用压缩时,更新不会以离散块的形式接收(原因很明显)。禁用压缩(通过向<system.webServier>添加<urlCompression>元素)可以解决问题:

<urlCompression doStaticCompression="true" doDynamicCompression="false" />

但是,这会禁用站点范围内的压缩。我想保留所有其他控制器和/或动作的压缩,除了这个。这可能吗?或者我将不得不创建一个新的网站/区域与自己的web.config?欢迎提出任何建议。

注:写HTTP响应的代码是:

var response = HttpContext.Response;
response.Write(s);
response.Flush();

在ASP中可以选择性地禁用gzip压缩吗?NET/IIS 7

@Aristos的回答将适用于WebForms,但在他的帮助下,我已经适应了一个更内联的解决方案。NET/MVC方法。

创建一个新的过滤器来提供gzip功能:

public class GzipFilter : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        base.OnActionExecuted(filterContext);
        var context = filterContext.HttpContext;
        if (filterContext.Exception == null && 
            context.Response.Filter != null &&
            !filterContext.ActionDescriptor.IsDefined(typeof(NoGzipAttribute), true))
        {
            string acceptEncoding = context.Request.Headers["Accept-Encoding"].ToLower();;
            if (acceptEncoding.Contains("gzip"))
            {
                context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
                context.Response.AppendHeader("Content-Encoding", "gzip");
            }                       
            else if (acceptEncoding.Contains("deflate"))
            {
                context.Response.Filter = new DeflateStream(context.Response.Filter, CompressionMode.Compress);
                context.Response.AppendHeader("Content-Encoding", "deflate");
            } 
        }
    }
}

创建NoGzip属性:

public class NoGzipAttribute : Attribute {
}

阻止IIS7使用web.config:

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

在global .asax.cs中注册你的全局过滤器:

protected void Application_Start()
{
    ...
    GlobalFilters.Filters.Add(new GzipFilter());
}

最后,消耗NoGzip属性:

public class MyController : AsyncController
{
    [NoGzip]
    [NoAsyncTimeout]
    public void GetProgress(int id)
    {
        AsyncManager.OutstandingOperations.Increment();
        ...
    }
    public ActionResult GetProgressCompleted() 
    {
        ...
    }
}

注:再次感谢@Aristos,感谢他的想法和解决方案。

我发现了一个更简单的方法。你可以选择性地禁用默认的IIS压缩(假设它在你的web.config中是启用的),而不是选择性地进行自己的压缩。

只要删除请求的accept-encoding编码头,IIS就不会压缩页面。

(global.asax.cs:)

protected void Application_BeginRequest(object sender, EventArgs e)
{
    try
    {
        HttpContext.Current.Request.Headers["Accept-Encoding"] = "";
    }
    catch(Exception){}
}

如果您自己设置gzip压缩,在您希望的时候选择呢?在Application_BeginRequest上检查你什么时候想做压缩,什么时候不做压缩。下面是一个示例代码:

protected void Application_BeginRequest(Object sender, EventArgs e)
{
    string cTheFile = HttpContext.Current.Request.Path;
    string sExtentionOfThisFile = System.IO.Path.GetExtension(cTheFile);
    if (sExtentionOfThisFile.Equals(".aspx", StringComparison.InvariantCultureIgnoreCase))
    {
        string acceptEncoding = MyCurrentContent.Request.Headers["Accept-Encoding"].ToLower();;
        if (acceptEncoding.Contains("deflate") || acceptEncoding == "*")
        {
            // defalte
            HttpContext.Current.Response.Filter = new DeflateStream(prevUncompressedStream,
                CompressionMode.Compress);
            HttpContext.Current.Response.AppendHeader("Content-Encoding", "deflate");
        } else if (acceptEncoding.Contains("gzip"))
        {
            // gzip
            HttpContext.Current.Response.Filter = new GZipStream(prevUncompressedStream,
                CompressionMode.Compress);
            HttpContext.Current.Response.AppendHeader("Content-Encoding", "gzip");
        }       
    }
}