gzip压缩不起作用,并且无法在chrome中获得304

lku*_*ylo 6 compression asp.net-mvc caching gzip google-chrome

我正在我的asp.net mvc 5应用程序中使用压缩和缓存机制.

我正在发送带有以下缓存标头的文件:

            Response.Cache.SetCacheability(HttpCacheability.Public);
            Response.Cache.SetExpires(DateTime.UtcNow.AddYears(1).ToUniversalTime());
            Response.Cache.SetLastModified(System.IO.File.GetLastWriteTime(serverPath).ToUniversalTime());
            Response.AppendHeader("Vary", "Accept-Encoding");
Run Code Online (Sandbox Code Playgroud)

IE11,Edge,Firefox,都在F5刷新时发送If-Modified-Since标头,但不是Chrome.为什么这样以及如何解决它?在Chrome中,我获得了200个状态代码,文件从缓存中加载.

我遇到的第二个问题是启用gzip压缩.我有一个标准的动作过滤器:

public class CompressContentMvcAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            GZipEncodePage();
        }

        private bool IsGZipSupported()
        {
            string AcceptEncoding = HttpContext.Current.Request.Headers["Accept-Encoding"];

            if (!string.IsNullOrEmpty(AcceptEncoding) &&
                    (AcceptEncoding.Contains("gzip") || AcceptEncoding.Contains("deflate")))
            {
                return true;
            }

            return false;
        }

        private void GZipEncodePage()
        {
            HttpResponse Response = HttpContext.Current.Response;

            if (IsGZipSupported())
            {
                string AcceptEncoding = HttpContext.Current.Request.Headers["Accept-Encoding"];

                if (AcceptEncoding.Contains("gzip"))
                {
                    Response.Filter = //new GZipCompressionService().CreateCompressionStream(Response.Filter);
                        new System.IO.Compression.GZipStream(Response.Filter,
                                                System.IO.Compression.CompressionMode.Compress);
                    Response.Headers.Remove("Content-Encoding");
                    Response.AppendHeader("Content-Encoding", "gzip");
                }
                else
                {
                    Response.Filter =// new DeflateCompressionService().CreateCompressionStream(Response.Filter);
                        new System.IO.Compression.DeflateStream(Response.Filter,
                                                System.IO.Compression.CompressionMode.Compress);
                    Response.Headers.Remove("Content-Encoding");
                    Response.AppendHeader("Content-Encoding", "deflate");
                }
            }

            // Allow proxy servers to cache encoded and unencoded versions separately
            Response.AppendHeader("Vary", "Content-Encoding");
        }
    }
Run Code Online (Sandbox Code Playgroud)

我在我的操作方法上应用此过滤器返回应用程序资产,但它获得了Transfer-Encoding:为每个文件分块,而不是gziped.这个过滤器是从我以前的项目中复制过来的,它仍在工作中.这可能是IIS服务器的问题吗?本地我有一个IIS 10和.NET 4.7,它的旧应用程序,它的工作原理是在IIS 8.5和框架4.5上托管.想不出别的什么.我在第二天谷歌搜索,找不到任何线索.我对IIS中的压缩不感兴趣.

[编辑]

我从回复得到的标题:

 HTTP/1.1 200 OK
Cache-Control: public
Content-Type: text/javascript
Expires: Sat, 18 May 2019 08:58:48 GMT
Last-Modified: Thu, 10 May 2018 13:26:02 GMT
Vary: Content-Encoding
Server: Microsoft-IIS/10.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 18 May 2018 08:58:48 GMT
Transfer-Encoding: chunked
Run Code Online (Sandbox Code Playgroud)

pfx*_*pfx 0

我总是使用 Fiddler 来检查此类挑战。

F5/If-Modified-Since 问题。

如果已经设置了过期标头并且其日期时间值仍然是实际的,Chrome 就不会发出新请求。因此 Chrome 尊重您预期的缓存行为。当通过其他浏览器浏览您的网站时,您会发现这些浏览器也不会发送对这些资产的任何请求。F5很“特殊”,它是强制刷新。

分块/gzip 问题

清除浏览器缓存并检查第一个响应。Fiddler 将显示“响应正文已编码”,这意味着已压缩(gzip 或 deflate)。

您是否看到 Transfer-Encoding 分块取决于 Content-Length 标头是否存在。请参阅下面的回复中的差异。如果您不希望分块的传输编码设置内容长度标头。

Content-Type: text/javascript; charset=utf-8
Content-Encoding: gzip
Expires: Sat, 25 May 2019 13:14:11 GMT
Last-Modified: Fri, 25 May 2018 13:14:11 GMT
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
Content-Length: 5292

Content-Type: text/javascript; charset=utf-8
Transfer-Encoding: chunked
Content-Encoding: gzip
Expires: Sat, 25 May 2019 13:14:11 GMT
Last-Modified: Fri, 25 May 2018 13:14:11 GMT
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
Run Code Online (Sandbox Code Playgroud)

因为您是通过自己的代码而不是通过 IIS 静态文件模块来处理资产服务,所以您必须自己处理所有响应标头。