it-swarm.com.ru

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

Я пытаюсь реализовать сжатие 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 конфигурациям сервера). А также в приведенном выше коде я не получаю последние две строки, почему они используются и какова цель этих строк. Пожалуйста, объясни!

Спасибо

75
Prashant

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

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

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

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

27
Ben Scheirman

Вот решение для CSS и Javascript файлов

<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>

Кредит: Как GZip на ASP.NET и GoDaddy

41
dortzur

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

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

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

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

На каждый запрос есть свой ответ Steam. Размещенный вами код присоединяется только к потоку ответов 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" /> 

..

Ричард

11
intermension

это может быть полезно для вас, это принимает сжатие 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");
        }
    } 
11
Nudier Mena

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

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

3
rizzle

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

2
gix

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

0
Chawathe Vipul

Вы можете просто добавить следующее в ваш файл 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
Rick