Как реализовать сжатие GZip в ASP.NET?

81

Я пытаюсь реализовать сжатие GZip для моей страницы asp.net (включая мои файлы CSS и JS). Я пробовал следующий код, но он сжимает только мою страницу .aspx (нашел ее в YSlow )

HttpContext context = HttpContext.Current;
context.Response.Filter = new GZipStream(context.Response.Filter, CompressionMode.Compress);
HttpContext.Current.Response.AppendHeader("Content-encoding", "gzip");
HttpContext.Current.Response.Cache.VaryByHeaders["Accept-encoding"] = true;

Приведенный выше код сжимает только мой код страницы .aspx (разметку), а не файлы CSS и JS, которые включены как внешние файлы. Скажите, пожалуйста, как я могу реализовать сжатие GZip в ASP.NET с помощью кода (потому что я нахожусь на сервере общего хостинга, где у меня нет доступа к конфигурациям сервера IIS). А также в приведенном выше коде я не понимаю последние две строки, почему они используются и какова цель этих строк. Пожалуйста, объясни!

Прашант
источник
Не совсем дубликат: stackoverflow.com/questions/6992524
jpaugh

Ответы:

28

Для сжатия файлов JS и CSS вам действительно нужно обрабатывать это на уровне IIS, поскольку эти файлы отображаются напрямую без среды выполнения ASP.NET.

Вы можете сделать сопоставление расширений JSX и CSSX в IIS с aspnet_isapi.dll, а затем воспользоваться вашим почтовым индексом, но IIS, вероятно, сделает это за вас лучше.

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

Параметр кеширования Accept-encoding используется для того, чтобы кешированная версия содержимого, сжатого с помощью gzip, не отправлялась в браузер, который запрашивал только text / html.

Бен Шейрман
источник
4
Привет @Ben! Не могли бы вы рассказать мне, как сжимать мои файлы с помощью IIS, какие все настройки мне нужно выполнить, хотя у меня нет доступа к конфигурациям IIS, но я постараюсь это сделать. Подскажите пожалуйста, как сжимать файлы с помощью IIS ?? Благодаря!
Prashant
4
stackoverflow.com/a/6992948/8479 подробно описывает простое изменение web.config, необходимое для IIS7 или более поздней версии.
Рори
47

Вот решение для файлов css и javascript. Добавьте следующий код в <system.webServer> внутри вашего файла web.config:

<configuration>
  ...
  <system.webserver>
     ...
      <httpCompression>
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
        <dynamicTypes>
          <add mimeType="text/*" enabled="true"/>
          <add mimeType="message/*" enabled="true"/>
          <add mimeType="application/javascript" enabled="true"/>
          <add mimeType="*/*" enabled="false"/>
        </dynamicTypes>
        <staticTypes>
          <add mimeType="text/*" enabled="true"/>
          <add mimeType="message/*" enabled="true"/>
          <add mimeType="application/javascript" enabled="true"/>
          <add mimeType="*/*" enabled="false"/>
        </staticTypes>
      </httpCompression>
      <urlCompression doStaticCompression="true" doDynamicCompression="true"/>
    ...
  </system.webserver>
  ...
<configuration>

Кредит: Как использовать GZip в ASP.NET и GoDaddy

Дорцур
источник
4
последняя строка должна быть удалена
JeffT
1
правда, но я бы добавил открывающий <system.webServer> ... чтобы мы знали, где разместить конфигурацию.
Карлос Р Балебона
Я добавил тот же код, но файлы не сжимаются
Зишан Ахмад Халил
Мне нужно что-то еще добавить?
Зишан Ахмад Халил
16

Это может быть полезно, если вы попробуете, это поддерживает сжатие deflate и gzip.

    void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication app = sender as HttpApplication;
        string acceptEncoding = app.Request.Headers["Accept-Encoding"];
        Stream prevUncompressedStream = app.Response.Filter;

        if (app.Context.CurrentHandler == null)
            return;

        if (!(app.Context.CurrentHandler is System.Web.UI.Page ||
            app.Context.CurrentHandler.GetType().Name == "SyncSessionlessHandler") ||
            app.Request["HTTP_X_MICROSOFTAJAX"] != null)
            return;

        if (acceptEncoding == null || acceptEncoding.Length == 0)
            return;

        acceptEncoding = acceptEncoding.ToLower();

        if (acceptEncoding.Contains("deflate") || acceptEncoding == "*")
        {
            // deflate
            app.Response.Filter = new DeflateStream(prevUncompressedStream,
                CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "deflate");
        }
        else if (acceptEncoding.Contains("gzip"))
        {
            // gzip
            app.Response.Filter = new GZipStream(prevUncompressedStream,
                CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "gzip");
        }
    } 
Nudier Mena
источник
2
Большое спасибо за этот код. Мне нужно было сжать / сжимать содержимое определенного сайта, у меня нет доступа к консоли IIS, и это мне помогло. Просто вопрос: похоже, этот код сжимает все файлы aspx и gziping CSS и ScriptResources, но не gziping никаких файлов .js. Есть способ сделать это? Благодарю.
Рафаэль Мерлин
Это неправильно, так как вы не обрабатываете инструкции качества , как это: gzip;q=0,deflate. singular.co.nz/2008/07/…
oligofren
11

Причина, по которой он сжимает только ваш файл ASPX, заключается в том, что написанный вами код встроен только в файл ASPX. Файл ASPX - это отдельный запрос от любого связанного содержимого, которое он содержит. Итак, если у вас есть страница ASPX, содержащая:

<img src="www.example.com\exampleimg.jpg" alt="example" />

Это составит 2 запроса (не считая DNS-запросов) от вашего браузера к ресурсам:

  1. для страницы aspx и
  2. для изображения, содержащегося на странице aspx.

На каждый запрос есть своя пара ответов. Опубликованный вами код прикрепляется только к потоку ответов ASPX, поэтому сжимается только ваша страница ASPX. Строки 1 и 2 вашего опубликованного кода, по сути, берут на себя нормальный поток ответов страницы и вводят некоторый код «среднего человека», который в этом случае съедает и сжимает нормальный выходной поток с потоком GZip и вместо этого отправляет его по сети.

Строки 3 и 4 устанавливают заголовки ответа. Все HTTP-запросы и ответы имеют заголовки, которые отправляются перед содержанием. Они настраивают запрос / ответ так, чтобы сервер и клиент знали, что и как отправляется.

В этом случае строка 3 информирует браузер клиента о том, что поток ответа сжимается через gzip и, следовательно, перед отображением его необходимо распаковать в браузере клиента.

А в строке 4 просто включается заголовок ответа Accept-Encoding. В противном случае это не было бы в ответе.

Вы можете написать / получить подключаемые модули, которые позволяют сжимать множество других типов MIME, таких как * .js и * .css, но вам лучше просто использовать встроенные функции сжатия IIS.

Вы не сказали, какую версию IIS вы используете, но если бы это был IIS 7.0, вам потребовалось бы включить что-то вроде следующего в <system.webserver>раздел вашего файла web.config:

<httpCompression> 
  <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" /> 
 <staticTypes>
         <add mimeType="text/*" enabled="true" />
      </staticTypes>
</httpCompression> 
<urlCompression doStaticCompression="true" /> 

..

Ричард

вмешательство
источник
Действительно потрясающие описания
Rakeshyadvanshi
3

В IIS7 все запросы отправляются в .net, поэтому вам нужно будет создать HttpModule, который добавит эти заголовки ко всем ответам.

Без IIS7 и на общем хостинге вам пришлось бы создать обработчик, который отображал бы расширение .net-файла, которое вы не используете (например, .asmx), а в web.config укажите, что файлы .asmx переходят в ваш HttpHandler, который установлен чтобы переписать путь в .jpg или что-то еще и установить там заголовок.

Миссаги
источник
2

Чтобы ответить на ваш последний вопрос. Эти две строки устанавливают заголовки HTTP для ответа, отправляемого обратно в браузер. Content-Encodingсообщает браузеру, что ответ закодирован как gzip и его нужно декодировать. Последняя строка добавляется Accept-Encodingк заголовку Vary . С его помощью браузер или прокси-серверы могут определить, был ли ответ уникальным или на него влияют некоторые другие заголовки, и настроить их кеширование.

gix
источник
0

Добавьте расширение .aspx к .css или .js файлу. Используйте <% @ Page ContentType = "text / css"%> или javascript в файле, чтобы обслуживать его с правильным типом MIME. & используйте URL Rewrite, чтобы скрыть это от браузеров пользовательских агентов. К заголовку ответа кодирования содержимого добавляется gzip, чтобы указать, что gzip - это метод, используемый для сжатия. Установите для заголовка ответа значение Accept-Encoding, чтобы все кеши знали, какая страница (сжатая или несжатая) должна обслуживаться, в зависимости от заголовка запроса Accept-Encoding. Я подробно остановился на этом на https://stackoverflow.com/a/14509007/1624169

Чават Випул С
источник
0

Вы можете просто добавить в свой файл web.config внутри <system.webServer>элемента следующее:

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

ПРИМЕЧАНИЕ. Если вы используете старую версию IIS (ниже v7.5), вы можете установить для doDynamicCompression значение false, потому что процесс был интенсивным. Эти проблемы были устранены в IIS 7.5.

Ссылка: https://docs.microsoft.com/en-us/iis/configuration/system.webserver/urlcompression

Рик
источник
0

Либо сделайте это с помощью файла web.config

<system.webServer>
    <httpCompression>
        <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/>
        <dynamicTypes>
            <add mimeType="text/*" enabled="true"/>
            <add mimeType="message/*" enabled="true"/>
            <add mimeType="application/javascript" enabled="true"/>
            <add mimeType="*/*" enabled="false"/>
        </dynamicTypes>
        <staticTypes>
            <add mimeType="text/*" enabled="true"/>
            <add mimeType="message/*" enabled="true"/>
            <add mimeType="application/javascript" enabled="true"/>
            <add mimeType="*/*" enabled="false"/>
        </staticTypes>
    </httpCompression>
    <urlCompression doStaticCompression="true" doDynamicCompression="true"/>
</system.webServer>

Или вы можете сделать это через IIS. Для сжатия файлов JS и CSS вам действительно нужно обрабатывать это на уровне IIS, поскольку эти файлы отображаются напрямую без среды выполнения ASP.NET.

Вы можете сделать сопоставление расширений JSX и CSSX в IIS с aspnet_isapi.dll, а затем воспользоваться вашим почтовым индексом, но IIS, вероятно, сделает это за вас лучше.

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

Параметр кеширования Accept-encoding используется для того, чтобы кешированная версия содержимого, сжатого с помощью gzip, не отправлялась в браузер, который запрашивал только text / html.

Код
источник