Сжатие GZIP не работает и не может получить 304 в Chrome - PullRequest
0 голосов
/ 17 мая 2018

Я работаю над механизмом сжатия и кэширования в моем приложении 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");

IE11,Edge, Firefox, все отправляют заголовок If-Modified-Since при обновлении F5, но не 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");
        }
    }

Я применяю этот фильтр к своему методу действия, возвращающему активы приложения, но он получил Transfer-Encoding: chunked для каждого файла, а не gziped.Этот фильтр скопирован из моего предыдущего проекта, и ожидается, что он все еще работает.Может ли быть проблема с сервером IIS?Локально у меня есть IIS 10 и .NET 4.7, старое приложение, в котором оно работает, размещено на IIS 8.5 и framework 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

1 Ответ

0 голосов
/ 25 мая 2018

Я всегда использую Fiddler для проверки подобных задач.

Выпуск F5 / If-Modified-Since.

Chrome просто не выполняет новый запрос, если был установлен заголовок expires и его значение datetime все еще актуально. Таким образом, Chrome уважает ваше ожидаемое поведение при кэшировании. При навигации по вашему веб-сайту через другой браузер вы увидите, что они также не отправляют никаких запросов на эти ресурсы. F5 «особенный», это принудительное обновление.

Выпуск по частям / gzip

Очистите кеш браузера и проверьте первый ответ. Fiddler покажет «тело ответа закодировано», что означает сжатие (gzip или deflate).

Видите ли вы, что кодирование передачи-кодирования зависит от наличия заголовка Content-Length. Смотрите разницу в ответах ниже. Если вы не хотите, чтобы chunked 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

Поскольку вы обрабатываете обслуживание ресурсов с помощью своего собственного кода, а не с помощью модуля статических файлов IIS, вам приходится иметь дело со всеми заголовками ответов самостоятельно.

...