Wie implementiere ich die GZip-Komprimierung in ASP.NET?

81

Ich versuche, die GZip-Komprimierung für meine asp.net-Seite (einschließlich meiner CSS- und JS-Dateien) zu implementieren. Ich habe den folgenden Code ausprobiert, aber er komprimiert nur meine ASPX-Seite (gefunden von 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;

Der obige Code komprimiert nur meinen ASPX-Seitencode (Markup), nicht die CSS- und JS-Dateien, die als externe Dateien enthalten sind. Bitte sagen Sie mir, wie ich die GZip-Komprimierung in ASP.NET mithilfe von Code implementieren kann (da ich mich auf einem gemeinsam genutzten Hosting-Server befinde, auf dem ich keinen Zugriff auf IIS-Serverkonfigurationen habe). Und auch im obigen Code bekomme ich nicht die letzten beiden Zeilen, warum sie verwendet werden und was der Zweck dieser Zeilen ist. Bitte erkläre!

Prashant
quelle
Nicht ganz ein Duplikat: stackoverflow.com/questions/6992524
jpaugh

Antworten:

28

Zum Komprimieren von JS- und CSS-Dateien müssen Sie dies tatsächlich auf IIS-Ebene behandeln, da diese Dateien direkt ohne die ASP.NET-Laufzeit gerendert werden.

Sie könnten eine JSX- und CSSX-Erweiterungszuordnung in IIS zur aspnet_isapi.dll erstellen und dann Ihre Postleitzahl nutzen, aber IIS wird dies wahrscheinlich besser für Sie erledigen.

Der Header für die Inhaltscodierung teilt dem Browser mit, dass er den Inhalt vor dem Rendern entpacken muss. Einige Browser sind klug genug, um dies anhand der Form des Inhalts herauszufinden, aber es ist besser, es einfach zu sagen.

Die Cache-Einstellung zum Akzeptieren der Codierung ist vorhanden, damit eine zwischengespeicherte Version des komprimierten Inhalts nicht an einen Browser gesendet wird, der nur Text / HTML anfordert.

Ben Scheirman
quelle
4
Hallo @Ben, können Sie mir bitte sagen, wie ich meine Dateien mit IIS komprimieren soll, welche Einstellungen ich vornehmen muss? Ich habe zwar keinen Zugriff auf IIS-Konfigurationen, aber ich werde versuchen, dies zu tun. Bitte sagen Sie mir, wie man Dateien mit IIS komprimiert. Vielen Dank!
Prashant
4
stackoverflow.com/a/6992948/8479 beschreibt die einfache Änderung von web.config, die für IIS7 oder höher erforderlich ist.
Rory
46

Hier ist die Lösung für CSS- und Javascript-Dateien. Fügen Sie den folgenden Code in Ihre web.config-Datei ein:

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

Credit: Wie man auf ASP.NET und GoDaddy GZip

dortzur
quelle
4
Die letzte Zeile sollte entfernt werden
JeffT
stimmt, aber ich würde tatsächlich die Öffnung <system.webServer> hinzufügen ... damit wir wissen, wo die Konfiguration abgelegt werden soll.
Carlos R Balebona
Ich habe den gleichen Code hinzugefügt, aber die Dateien werden nicht komprimiert
Zeeshan Ahmad Khalil
Muss ich noch etwas hinzufügen?
Zeeshan Ahmad Khalil
16

Dies kann nützlich sein, wenn Sie es ausprobieren. Dies akzeptiert die Deflate- und GZIP-Komprimierung.

    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
quelle
2
Vielen Dank für diesen Code. Ich musste den Inhalt einer bestimmten Site gzipen / entleeren, auf die ich keinen Zugriff auf die IIS-Konsole habe, und dies hat mir geholfen. Nur eine Frage: Dieser Code scheint alle Aspx-Dateien zu entleeren und CSS und ScriptResources zu gzipen, aber es werden keine .js-Dateien gzipiert. Gibt es eine Möglichkeit, das zu tun? Vielen Dank.
Rafael Merlin
Dies ist falsch, da Sie Qualitätsanweisungen nicht wie folgt behandeln : gzip;q=0,deflate. singular.co.nz/2008/07/…
Oligofren
11

Der Grund dafür, dass nur Ihre ASPX-Datei komprimiert wird, ist, dass der von Ihnen geschriebene Code nur in die ASPX-Datei eingebettet ist. Eine ASPX-Datei ist eine separate Anforderung von allen darin enthaltenen verknüpften Inhalten. Wenn Sie also eine ASPX-Seite haben, die Folgendes enthält:

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

Dies entspricht 2 Anfragen (abgesehen von DNS-Lookups) von Ihrem Browser an die Ressourcen:

  1. für die aspx Seite und
  2. für das auf der aspx-Seite enthaltene Bild.

Jede Anfrage hat ihren eigenen Antwortdampf. Der von Ihnen veröffentlichte Code wird nur an den ASPX-Antwortstrom angehängt, weshalb nur Ihre ASPX-Seite komprimiert wird. Die Zeilen 1 und 2 Ihres veröffentlichten Codes übernehmen im Wesentlichen den normalen Antwortstrom der Seite und fügen einen "Middle Man" -Code ein, der in diesem Fall den normalen Ausgabestream mit einem GZip-Stream frisst und komprimiert und diesen stattdessen über den Draht sendet.

Die Zeilen 3 und 4 richten die Antwortheader ein. Alle http-Anfragen und -Antworten haben Header, die vor dem Inhalt gesendet werden. Diese richten die Anfrage / Antwort so ein, dass Server und Client wissen, was und wie gesendet wird.

In diesem Fall informiert Zeile 3 den Client-Browser darüber, dass der Antwortstrom über gzip komprimiert wird und daher vor der Anzeige vom Client-Browser dekomprimiert werden muss.

Und Zeile 4 aktiviert einfach den Accept-Encoding-Header der Antwort. Dies wäre sonst in der Antwort nicht enthalten gewesen.

Es gibt steckbare Module, die Sie schreiben / erhalten können, mit denen Sie eine Vielzahl anderer MIME-Typen wie * .js und * .css komprimieren können. Sie sollten jedoch nur die integrierte Komprimierungsfunktion von IIS verwenden.

Sie haben nicht gesagt, welche Version von IIS Sie verwenden, aber wenn es IIS 7.0 wäre, müssten Sie Folgendes in den <system.webserver>Abschnitt Ihrer web.config-Datei aufnehmen:

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

..

Richard

intermension
quelle
Wirklich tolle Beschreibungen
Rakeshyadvanshi
3

In IIS7 gehen alle Anforderungen an .net, sodass Sie ein HttpModule erstellen müssen, das diese Header zu allen Antworten hinzufügt.

Ohne IIS7 und beim Shared Hosting müssten Sie einen Handler erstellen, der eine nicht verwendete .net-Dateierweiterung zuordnet (wie .asmx), und in der web.config angeben, dass .asmx-Dateien an Ihren festgelegten HttpHandler gesendet werden um den Pfad zu .jpg oder was auch immer umzuschreiben und dort auch den Header zu setzen.

Missaghi
quelle
2

Um Ihre letzte Frage zu beantworten. Diese beiden Zeilen legen HTTP-Header für die an den Browser zurückgesendete Antwort fest. Content-Encodingteilt dem Browser mit, dass die Antwort als gzip codiert ist und dekodiert werden muss. Die letzte Zeile wird Accept-Encodingzum Vary-Header hinzugefügt . Damit können der Browser oder die Proxys feststellen, ob die Antwort eindeutig war oder von bestimmten anderen Headern beeinflusst wird, und deren Caching anpassen.

gix
quelle
0

Fügen Sie der CSS- oder JS-Datei die ASPX-Erweiterung hinzu. Verwenden Sie <% @ Page ContentType = "text / css"%> oder Javascript in der Datei, um sie mit dem richtigen MIME-Typ bereitzustellen. & Verwenden Sie URL Rewrite, um dies vor den Browsern des Benutzeragenten zu verbergen. Der inhaltscodierende Antwortheader wird an gzip angehängt, um zu verdeutlichen, dass gzip die Methode zur Komprimierung ist. Der Antwortheader ist auf Accept-Encoding gesetzt, damit alle Caches wissen, welche Seite (komprimiert oder unkomprimiert) bedient werden soll. Dies hängt vom Accept-Encoding-Header der Anforderung ab. Ich habe dies unter https://stackoverflow.com/a/14509007/1624169 ausgeführt

Chawathe Vipul S.
quelle
0

Sie können Ihrer web.config-Datei innerhalb des <system.webServer>Elements einfach Folgendes hinzufügen :

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

ANMERKUNG: Wenn Sie eine ältere Version von IIS (weniger als Version 7.5) verwenden, möchten Sie möglicherweise doDynamicCompression auf false setzen, da der Prozess CPU-intensiv war. Diese Probleme wurden in IIS 7.5 behoben.

Referenz: https://docs.microsoft.com/en-us/iis/configuration/system.webserver/urlcompression

Rick
quelle
0

Entweder mit der Datei 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>

Oder Sie können dies über IIS tun. Zum Komprimieren von JS- und CSS-Dateien müssen Sie dies tatsächlich auf IIS-Ebene behandeln, da diese Dateien direkt ohne die ASP.NET-Laufzeit gerendert werden.

Sie könnten eine JSX- und CSSX-Erweiterungszuordnung in IIS zur aspnet_isapi.dll erstellen und dann Ihre Postleitzahl nutzen, aber IIS wird dies wahrscheinlich besser für Sie erledigen.

Der Header für die Inhaltscodierung teilt dem Browser mit, dass er den Inhalt vor dem Rendern entpacken muss. Einige Browser sind klug genug, um dies anhand der Form des Inhalts herauszufinden, aber es ist besser, es einfach zu sagen.

Die Cache-Einstellung zum Akzeptieren der Codierung ist vorhanden, damit eine zwischengespeicherte Version des komprimierten Inhalts nicht an einen Browser gesendet wird, der nur Text / HTML anfordert.

Code
quelle