web-dev-qa-db-fra.com

Comment implémenter la compression GZip dans ASP.NET?

J'essaie d'implémenter la compression GZip pour ma page asp.net (y compris mes fichiers CSS et JS). J'ai essayé le code suivant, mais il compresse uniquement ma page .aspx (trouvée à partir de 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;

Le code ci-dessus ne fait que compresser mon code de page .aspx (balisage), pas les fichiers CSS et JS inclus en tant que fichiers externes. Veuillez m'expliquer comment puis-je implémenter la compression GZip dans ASP.NET à l'aide de code (car je réside sur un serveur d'hébergement partagé où je n'ai pas accès aux configurations de serveur IIS). Et aussi dans le code ci-dessus, je ne comprends pas les deux dernières lignes, pourquoi elles sont utilisées et quel est le but de ces lignes. S'il vous plaît, expliquez!

Merci

75
Prashant

Pour compresser les fichiers JS & CSS, vous devez en fait le gérer au niveau IIS, car ces fichiers sont rendus directement sans le runtime ASP.NET.

Vous pouvez créer un mappage d'extension JSX et CSSX dans IIS avec aspnet_isapi.dll, puis tirer parti de votre code postal, mais IIS vous permettra probablement de mieux le faire.

L'en-tête de codage du contenu indique au navigateur qu'il doit décompresser le contenu avant le rendu. Certains navigateurs sont assez intelligents pour comprendre cela quand même, en fonction de la forme du contenu, mais il est préférable de simplement le dire.

Le paramètre de cache Accept-encoding existe pour qu'une version en cache du contenu compressé ne soit pas envoyée à un navigateur qui ne demande que du texte/html.

27
Ben Scheirman

Voici la solution pour les fichiers css et 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>

Crédit: Comment GZip sur ASP.NET et GoDaddy

41
dortzur

La seule raison pour laquelle il compresse votre fichier ASPX est que le code que vous avez écrit est uniquement intégré au fichier ASPX. Un fichier ASPX est une demande distincte de tout contenu lié qu'il contient. Donc, si vous avez une page ASPX qui contient: 

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

Cela équivaudrait à 2 demandes (recherches DNS de côté) de votre navigateur aux ressources:

  1. pour la page aspx et 
  2. pour l'image contenue par la page aspx.

Chaque demande a sa propre réponse Steam. Le code que vous avez publié est uniquement lié au flux de réponses ASPX, raison pour laquelle seule votre page ASPX est compressée. Les lignes 1 et 2 de votre code posté reprennent essentiellement le flux de réponse normal de la page et injectent un code "intermédiaire" qui, dans ce cas, mange et compresse le flux de sortie normal avec un flux GZip et l'envoie à la place.

Les lignes 3 et 4 configurent les en-têtes de réponse. Toutes les demandes et réponses http ont des en-têtes qui sont envoyés avant le contenu. Ceux-ci configurent la demande/réponse de sorte que le serveur et le client sachent ce qui est envoyé et comment. 

Dans ce cas, la ligne 3 informe le navigateur client que le flux de réponse est compressé via gzip et doit donc être décompressé par le navigateur client avant d'être affiché.

Et Line 4 active simplement l'en-tête Accept-Encoding de la réponse. Cela aurait autrement été absent de la réponse.

Il existe des modules enfichables que vous pouvez écrire/obtenir qui vous permettent de compresser un document comportant plusieurs types MIME, tels que * .js et * .css, mais il est préférable d’utiliser simplement la fonctionnalité de compression intégrée de IIS. 

Vous n'avez pas indiqué quelle verson de IIS vous utilisez, mais s'il s'agissait de IIS 7.0, il faudrait que vous incluez quelque chose comme ce qui suit dans la section <system.webserver> de votre fichier web.config:

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

..

Richard

11
intermension

cela peut être utile pour l'essayer, cela accepte les compressions par déflate et 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

Dans IIS7, toutes les demandes vont au réseau. Vous devez donc créer un HttpModule qui ajoute ces en-têtes à toutes les réponses.

Sans IIS7 et sur l'hébergement partagé, vous devez créer un gestionnaire mappant une extension de fichier .net que vous n'utilisez pas (comme .asmx) et dans le fichier web.config, spécifiez que les fichiers .asmx vont à votre HttpHandler qui est défini. pour réécrire le chemin en .jpg ou autre et définir l’en-tête là aussi.

3
rizzle

Pour répondre à ta dernière question. Ces deux lignes définissent des en-têtes HTTP pour la réponse renvoyée au navigateur. Content-Encoding indique au navigateur que la réponse est codée en tant que gzip et doit être décodée. La dernière ligne ajoute Accept-Encoding à l'en-tête Vary . Avec cela, le navigateur ou les mandataires peuvent déterminer si la réponse est unique ou est influencée par certains autres en-têtes et ajuster leur mise en cache.

2
gix

Ajoutez l'extension .aspx au fichier .css ou .js. Utilisez <% @ Page ContentType = "text/css"%> ou javascript dans le fichier pour le servir avec le type MIME correct. & utilisez URL Rewrite pour le masquer aux navigateurs d’agent d’utilisateur. Gzip est ajouté à l'en-tête de réponse de codage du contenu pour indiquer que gzip est la méthode utilisée pour effectuer la compression. Variez l'en-tête de réponse défini sur Accept-Encoding afin que tous les caches sachent quelle page (compressée ou non compressée) doit être servie dépend de l'en-tête Accept-Encoding de la requête. J'ai élaboré sur ceci à https://stackoverflow.com/a/14509007/1624169

0
Chawathe Vipul

Vous pouvez simplement ajouter les éléments suivants à votre fichier web.config dans l'élément <system.webServer>:

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

REMARQUE: Si vous utilisez une version antérieure de IIS (inférieure à la v7.5), vous souhaiterez peut-être définir la valeur false de doDynamicCompression car le processus nécessitait beaucoup de ressources en processeur. Ces problèmes ont été résolus dans IIS 7.5.

Référence: https://docs.Microsoft.com/en-us/iis/configuration/system.webserver/urlcompression

0
Rick

Soit le faire avec le fichier 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>

Ou vous pouvez le faire via IIS. Pour compresser les fichiers JS & CSS, vous devez en fait le gérer au niveau IIS, car ces fichiers sont rendus directement sans le runtime ASP.NET.

Vous pouvez créer un mappage d'extension JSX et CSSX dans IIS avec aspnet_isapi.dll, puis tirer parti de votre code postal, mais IIS fera probablement un meilleur travail pour vous. .

L'en-tête de codage du contenu indique au navigateur qu'il doit décompresser le contenu avant le rendu. Certains navigateurs sont assez intelligents pour comprendre cela quand même, en fonction de la forme du contenu, mais il est préférable de simplement le dire.

Le paramètre de cache Accept-encoding existe pour qu'une version en cache du contenu compressé ne soit pas envoyée à un navigateur qui ne demande que du texte/html.

0
JIYAUL MUSTAPHA