如果内容编码添加到标题

时间:2018-06-06 14:49:55

标签: asp.net gzip outputcache deflate content-encoding

我有一个控制器和一个动作。

public class LoginController
{
    [OutputCache(Duration = 10000, VaryByParam = "none")]
    public ActionResult Logout()
    {
        ......
    }
}

以上代码正常工作,输出缓存没有问题。一切都很好。

但是当我将下面的代码添加到Application_BeginRequest时出现了问题。我添加了页面图片。

 string encodings = app.Request.Headers.Get("Accept-Encoding");
 if (encodings != null)
 {
            // Check the browser accepts deflate or gzip (deflate takes preference)
            encodings = encodings.ToLower();

            if (encodings.Contains("gzip"))
            {
                app.Response.Filter = new GZipStream(app.Response.Filter, CompressionMode.Compress);
                app.Response.AppendHeader("Content-Encoding", "gzip");
            }
            else if (encodings.Contains("deflate"))
            {
                app.Response.Filter = new DeflateStream(app.Response.Filter, CompressionMode.Compress);
                app.Response.AppendHeader("Content-Encoding", "deflate");
            }

 }

The page is ....

1 个答案:

答案 0 :(得分:0)

您必须添加一个VaryByContentEncoding
没有一个版本,仅缓存1个版本。

如果高速缓存中的此版本是根据支持(例如)的请求构建的gzip压缩,此缓存的数据将以gzip格式压缩。
然后,相同的压缩数据也将被提供给不支持压缩或仅压缩的请求,从而产生您所看到的结果。

您必须确保缓存单独的版本; 1个未压缩,1个用于gizp,另一个用于放气。
这样可以根据网络浏览器支持的版本提供正确的版本。

[OutputCache(Duration = 10000, VaryByParam = "none", VaryByContentEncoding="gzip;deflate")]
public ActionResult Logout()
{
    // ...
}

编辑

除了缺少的VaryByContentEncoding,还有更多事情要做。

Application_BeginRequestOutputCacheAttribute玩的不好。
因此,缓存持续时间不再适用。 这必须与执行顺序以及在什么时候设置哪些标头有关。

与其依靠Application_BeginRequest来将压缩代码移至动作过滤器, 对于ASP.NET MVC而言,这是在请求管道内采取行动的建议方式。
请参见下面的CompressAttribute

通过示例,我将其应用于About上的即用型HomeController方法。
这次,结果符合预期,与请求和响应的HTTP标头匹配。

CompressAttribute:

public class CompressAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        HttpRequestBase request = filterContext.RequestContext.HttpContext.Request;
        HttpResponseBase response = filterContext.RequestContext.HttpContext.Response;

        string encodings = request.Headers.Get("Accept-Encoding");
        if (encodings != null)
        {
            // Check the browser accepts deflate or gzip (deflate takes preference)
            encodings = encodings.ToLower();

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

HomeController:

public class HomeController : Controller
{
    [Compress()]
    [OutputCache(Duration = 10, VaryByParam = "none", VaryByContentEncoding="gzip;deflate")]
    public ActionResult About()
    {
        ViewBag.Message = DateTime.Now.ToString("dd/MM/yy HH:mm:ss.fff");
        return View();
    }        
}