Як реалізувати стиснення 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 передбачено, щоб кешована версія зібраного вмісту не надсилалася браузеру, який вимагав лише текст / html.


4
Привіт @Ben, скажіть, будь ласка, як стискати свої файли за допомогою IIS, які всі налаштування я повинен виконати, хоча у мене немає доступу до конфігурацій IIS, але я спробую це зробити. Підкажіть, будь ласка, як стискати файли за допомогою IIS ?? Дякую!
Прашант,

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> ..., щоб ми знали, де розмістити конфігурацію.
Carlos R Balebona

Я додав той самий код, але файли не стискаються
Zeeshan Ahmad Khalil

Чи потрібно додати щось інше?
Зеешан Ахмад Халіл,

16

це може бути корисно для вас спробувати, це приймає дефляцію та стиснення 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");
        }
    } 

2
Велике спасибі за цей код. Мені потрібно було gzip / deflate вмісту певного сайту, я не маю доступу до консолі IIS, і це мені допомогло. Хоча лише запитання: Цей код, здається, дефляціює всі файли aspx, а також архівує CSS та ScriptResources, але не створює файли .js. Чи є спосіб зробити це? Дякую.
Рафаель Мерлін

Це неправильно, так як ви не обробляєте інструкції якості , як це: gzip;q=0,deflate. singular.co.nz/2008/07/…
олігофрен

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

..

Річард



3

У IIS7 всі запити надходять у .net, тож вам доведеться створити HttpModule, який додав би ці заголовки до всіх відповідей.

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


2

Відповісти на ваше останнє запитання. Ці два рядки встановлюють заголовки HTTP для відповіді, надісланої назад у браузер. Content-Encodingповідомляє браузеру, що відповідь закодована як gzip і її потрібно декодувати. Останній рядок додається Accept-Encodingдо заголовка Vary . За допомогою цього браузер або проксі-сервери можуть визначити, чи була відповідь унікальною чи на неї впливають деякі інші заголовки, та відрегулювати їх кешування.


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 передбачено, щоб кешована версія зібраного вмісту не надсилалася браузеру, який вимагав лише текст / html.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.