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

发布于 2024-11-01 07:43:11 字数 534 浏览 0 评论 0原文

我正在使用长期异步 HTTP 连接通过 AJAX 向客户端发送进度更新。启用压缩后,不会以离散块的形式接收更新(出于明显的原因)。禁用压缩(通过向 添加 元素)确实解决问题:

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

但是,这会禁用压缩站点范围内。我想为除此之外的所有其他控制器和/或操作保留压缩。这可能吗?或者我是否必须使用自己的 web.config 创建一个新站点/区域?欢迎任何建议。

PS 写入 HTTP 响应的代码是:

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

I am using a long-lived asynchronous HTTP connection to send progress updates to a client via AJAX. When compression is enabled, the updates are not received in discrete chunks (for obvious reasons). Disabling compression (by adding a <urlCompression> element to <system.webServier>) does solve the problem:

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

However, this disables compression site-wide. I would like to preserve compression for every other controller and/or action except for this one. Is this possible? Or am I going to have to create a new site/area with its own web.config? Any suggestions welcome.

P.S. the code that does the writing to the HTTP response is:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

多孤肩上扛 2024-11-08 07:43:11

@Aristos 的答案适用于 WebForms,但在他的帮助下,我采用了更符合 ASP.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 {
}

使用 web.config 防止 IIS7 进行 gzip 压缩:

<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() 
    {
        ...
    }
}

PS 再次非常感谢@Aristos ,感谢他有用的想法和解决方案。

@Aristos' answer will work for WebForms, but with his help, I've adapted a solution more inline with ASP.NET/MVC methodology.

Create a new filter to provide the gzipping functionality:

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");
            } 
        }
    }
}

Create the NoGzip attribute:

public class NoGzipAttribute : Attribute {
}

Prevent IIS7 from gzipping using web.config:

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

Register your global filter in Global.asax.cs:

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

Finally, consume the NoGzip attribute:

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

    public ActionResult GetProgressCompleted() 
    {
        ...
    }
}

P.S. Once again, many thanks to @Aristos, for his helpful idea and solution.

顾挽 2024-11-08 07:43:11

我找到了一种更简单的方法来做到这一点。您可以有选择地禁用默认的 IIS 压缩(假设在您的 web.config 中启用了它),而不是有选择地进行自己的压缩。

只需删除请求上的 Accept-Encoding 编码标头,IIS 就不会压缩页面。

(全局.asax.cs:)

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

I found a much easier way to do this. Instead of selectively doing your own compression, you can selectively disable the default IIS compression (assuming its enabled in your web.config).

Simply remove the accept-encoding encoding header on the request and IIS wont compress the page.

(global.asax.cs:)

protected void Application_BeginRequest(object sender, EventArgs e)
{
    try
    {
        HttpContext.Current.Request.Headers["Accept-Encoding"] = "";
    }
    catch(Exception){}
}
离鸿 2024-11-08 07:43:11

您可以自行设置 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");
        }       
    }
}

What about you set the gzip compression by your self, selectivle when you wish for ? On the Application_BeginRequest check when you like to make and when you dont make compression. Here is a sample code.

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");
        }       
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文