簡體   English   中英

可以在ASP.NET / IIS 7中有選擇地禁用gzip壓縮嗎?

[英]Can gzip compression be selectively disabled in ASP.NET/IIS 7?

我使用長期的異步HTTP連接通過AJAX向客戶端發送進度更新。 啟用壓縮時,不會以離散塊的形式接收更新(出於顯而易見的原因)。 禁用壓縮(通過向<system.webServier>添加<urlCompression>元素) 確實解決了問題:

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

但是,這會在站點范圍內禁用壓縮。 我想保留每個其他控制器和/或操作的壓縮,除了這個。 這可能嗎? 或者我將不得不用自己的web.config創建一個新的站點/區域? 歡迎任何建議。

PS寫入HTTP響應的代碼是:

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

@Aristos的回答將適用於WebForms,但在他的幫助下,我已經采用了更符合ASP.NET / MVC方法的解決方案。

創建一個新的過濾器以提供gzipping功能:

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進行gzipping攻擊:

<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,感謝他的有用的想法和解決方案。

我發現了一種更簡單的方法。 您可以選擇性地禁用默認的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壓縮,selectivle? 在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");
        }       
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM