Compresión de respuesta en ASP.NET Core

El ancho de banda de red es un recurso limitado. Reducir el tamaño de la respuesta suele aumentar la capacidad de respuesta de una aplicación, a menudo drásticamente. Una manera de reducir el tamaño de la carga útil es comprimir las respuestas de una aplicación.

Compresión con HTTPS

Las respuestas comprimidas a través de conexiones seguras pueden controlarse con la opción EnableForHttps, que está desactivada por defecto debido al riesgo de seguridad. El uso de compresión con páginas generadas dinámicamente puede exponer la aplicación a ataques de CRIME y BREACH. Los ataques de CRIME y BREACH pueden mitigarse en ASP.NET Core con tokens antifalsificación. Para obtener más información, vea Prevención de ataques de falsificación de solicitud entre sitios (XSRF/CSRF) en ASP.NET Core. Para obtener información sobre cómo mitigar ataques de BREACH, consulte mitigaciones en http://www.breachattack.com/

Incluso cuando EnableForHttps está deshabilitado en la aplicación, IIS, IIS Express y Azure App Service pueden aplicar gzip en el servidor web de IIS. Al revisar las cabeceras de respuesta, fíjese en el valor de Servidor. Un valor de encabezado de respuesta inesperado content-encoding puede ser el resultado del servidor web y no la configuración de la aplicación de ASP.NET Core.

Cuándo usar middleware de compresión de respuesta

Use tecnologías de compresión de respuesta basadas en servidor en IIS, Apache o Nginx. Es probable que el rendimiento del middleware de compresión de respuestas no se corresponda con el de los módulos de servidor. {El servidor HTTP.sys y el servidor Kestrel no ofrecen actualmente soporte de compresión integrada.

Use middleware de compresión de respuesta cuando la aplicación sea:

Compresión de las respuestas

Normalmente, cualquier respuesta no comprimida de forma nativa puede beneficiarse de la compresión de respuesta. Las respuestas no comprimidas de forma nativa suelen incluir CSS, JavaScript, HTML, XML y JSON. No comprima recursos comprimidos de forma nativa, como archivos PNG. Al intentar comprimir aún más una respuesta comprimida de forma nativa, cualquier pequeña reducción adicional en el tamaño y el tiempo de transmisión probablemente se verá eclipsada por el tiempo que se tarda en procesar la compresión. No comprima archivos menores de 150-1 000 bytes, según el contenido del archivo y la eficacia de la compresión. La sobrecarga de comprimir archivos pequeños puede producir un archivo comprimido mayor que el archivo sin comprimir.

Cuando un cliente puede procesar contenido comprimido, el cliente debe informar al servidor de sus funcionalidades enviando el encabezado Accept-Encoding con la solicitud. Cuando un servidor envía contenido comprimido, debe incluir información en el encabezado Content-Encoding sobre cómo se codifica la respuesta comprimida. Las designaciones de codificación de contenido admitidas por el middleware de compresión de respuesta se muestran en la tabla siguiente.

Accept-Encoding valores de encabezado Middleware compatible Descripción
br Sí (predeterminado) Formato de datos comprimidos de Brotli
deflate No Formato de datos comprimidos DEFLATE
exi No Intercambio XML eficaz de W3C
gzip Formato de archivo Gzip
identity Identificador "Sin codificación": la respuesta no debe codificarse.
pack200-gzip No Formato de transferencia de red para archivos de Java
* Cualquier codificación de contenido disponible no solicitada explícitamente

Para más información, consulte la Lista oficial de codificación de contenido de IANA.

El middleware de compresión de respuesta permite agregar proveedores de compresión adicionales para valores de encabezado personalizados Accept-Encoding. Para más información, consulte Proveedores personalizados en este artículo.

El middleware de compresión de respuesta es capaz de reaccionar a la ponderación del valor de calidad (qvalue, q) cuando lo envía el cliente para priorizar los esquemas de compresión. Para más información, consulte RFC 9110: Accept-Encoding.

Los algoritmos de compresión están sujetos a un equilibrio entre la velocidad de compresión y la eficacia de la compresión. La eficacia en este contexto hace referencia al tamaño de la salida después de la compresión. El tamaño más pequeño se logra mediante la compresión óptima.

Los encabezados implicados en la solicitud, envío, almacenamiento en caché y recepción de contenido comprimido se describen en la tabla siguiente.

Encabezado Rol
Accept-Encoding Enviado desde el cliente al servidor para indicar los esquemas de codificación de contenido aceptables para el cliente.
Content-Encoding Se envía desde el servidor al cliente para indicar la codificación del contenido en la carga.
Content-Length Cuando se produce la compresión, se elimina el encabezado Content-Length, ya que el contenido del cuerpo cambia cuando se comprime la respuesta.
Content-MD5 Cuando se produce la compresión, se elimina el encabezado Content-MD5, ya que el contenido del cuerpo ha cambiado y el hash ya no es válido.
Content-Type Especifica el tipo de MIME del contenido. Cada respuesta debe especificar su .Content-Type El middleware de compresión de respuesta comprueba este valor para determinar si se debe comprimir la respuesta. El middleware de compresión de respuesta especifica un conjunto de tipos de MIME predeterminados que puede codificar y pueden reemplazar o agregar la cama.
Vary Cuando el servidor envía un valor de Accept-Encoding a los clientes y servidores proxy, el encabezado Vary indica al cliente o proxy que debe almacenar en caché (variar) las respuestas en función del valor del encabezado Accept-Encoding de la solicitud. El resultado de devolver contenido con el encabezado Vary: Accept-Encoding es que las respuestas comprimidas y sin comprimir se almacenan en caché por separado.

Explore las características de Middleware de compresión de respuestas con la aplicación de ejemplo. En el ejemplo se muestra:

  • La compresión de las respuestas de la aplicación mediante Gzip y proveedores de compresión personalizados.
  • Cómo agregar un tipo de MIME a la lista predeterminada de tipos de MIME para la compresión.
  • Cómo agregar un proveedor de compresión de respuesta personalizada.

Configuración

En el código siguiente se muestra cómo habilitar el middleware de compresión de respuesta para los tipos y proveedores de compresión de MIME predeterminados (Brotli y Gzip):

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
});

var app = builder.Build();

app.UseResponseCompression();

app.MapGet("/", () => "Hello World!");

app.Run();

Notas:

Envíe una solicitud a la aplicación de ejemplo sin el encabezado Accept-Encoding y observe que la respuesta no está comprimida. El encabezado Content-Encoding no está en la colección de Encabezados de respuesta.

Por ejemplo, en Firefox Developer:

  • Seleccione la pestaña de red.
  • Haga clic con el botón derecho en la solicitud de la Lista de solicitud de red y seleccione Editar y reenviar.
  • Cambie Accept-Encoding: de gzip, deflate, br a none.
  • Seleccione Enviar.

Envíe una solicitud a la aplicación de ejemplo con un explorador mediante las herramientas de desarrollo y observe que la respuesta está comprimida. Los encabezados Content-Encoding y Vary están presentes en la respuesta.

Proveedores

Proveedores de compresión Brotli y Gzip

Use el BrotliCompressionProvider para comprimir las respuestas con el formato de datos comprimidos Brotli.

Si no se añaden explícitamente proveedores de compresión al CompressionProviderCollection:

  • El proveedor de compresión Brotli y el proveedor de compresión Gzip se agregan de forma predeterminada a la matriz de proveedores de compresión.
  • La compresión se establece de forma predeterminada en compresión Brotli cuando el formato de datos comprimidos Brotli es compatible con el cliente. Si Brotli no es compatible con el cliente, la compresión tiene como valor predeterminado Gzip cuando el cliente admite la compresión Gzip.

Nota:

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, use la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Cuando se agrega un proveedor de compresión, no se agregan otros proveedores. Por ejemplo, si el proveedor de compresión Gzip es el único proveedor agregado explícitamente, no se agregan otros proveedores de compresión.

El código siguiente:

  • Habilita la compresión de respuesta para las solicitudes HTTPS.
  • Agrega los proveedores de compresión de respuesta Brotli y Gzip.
using System.IO.Compression;
using Microsoft.AspNetCore.ResponseCompression;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
});

builder.Services.Configure<BrotliCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.Fastest;
});

builder.Services.Configure<GzipCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.SmallestSize;
});

var app = builder.Build();

app.UseResponseCompression();

app.MapGet("/", () => "Hello World!");

app.Run();

Establezca el nivel de compresión con BrotliCompressionProviderOptions y GzipCompressionProviderOptions. Los proveedores de compresión Brotli y Gzip utilizan de forma predeterminada el nivel de compresión más rápido, CompressionLevel.Fastest, que podría no producir la compresión más eficiente. Si se desea la compresión más eficiente, configure el middleware de compresión de respuesta para una compresión óptima.

Consulte la enumeración CompressionLevel para ver los valores que indican si una operación de compresión enfatiza la velocidad o el tamaño de compresión.

using System.IO.Compression;
using Microsoft.AspNetCore.ResponseCompression;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
});

builder.Services.Configure<BrotliCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.Fastest;
});

builder.Services.Configure<GzipCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.SmallestSize;
});

var app = builder.Build();

app.UseResponseCompression();

app.MapGet("/", () => "Hello World!");

app.Run();

Proveedores personalizados

Cree implementaciones de compresión personalizadas con ICompressionProvider. EncodingName representa la codificación de contenido que genera ICompressionProvider. El middleware de compresión de respuesta usa esta información para elegir el proveedor en función de la lista especificada en el encabezado Accept-Encoding de la solicitud.

Las peticiones a la aplicación de ejemplo con el encabezado Accept-Encoding: mycustomcompression devuelven una respuesta con un encabezado Content-Encoding: mycustomcompression. El cliente debe poder descomprimir la codificación personalizada para que funcione una implementación de compresión personalizada.

using Microsoft.AspNetCore.ResponseCompression;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
    options.Providers.Add<CustomCompressionProvider>();
});

var app = builder.Build();

app.UseResponseCompression();

app.MapGet("/", () => "Hello World!");

app.Run();
using Microsoft.AspNetCore.ResponseCompression;

public class CustomCompressionProvider : ICompressionProvider
{
    public string EncodingName => "mycustomcompression";
    public bool SupportsFlush => true;

    public Stream CreateStream(Stream outputStream)
    {
        // Replace with a custom compression stream wrapper.
        return outputStream;
    }
}

Con el código anterior, el ejemplo no comprime el cuerpo de la respuesta. Sin embargo, el ejemplo muestra dónde implementar un algoritmo de compresión personalizado.

tipos MIME

El middleware de compresión de respuesta especifica un conjunto predeterminado de tipos de MIME para la compresión. Consulte el código fuente para obtener una lista completa de los tipos de MIME admitidos.

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, use la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Reemplace o anexe tipos de MIME con ResponseCompressionOptions.MimeTypes. Tenga en cuenta que no se admiten tipos de MIME con caracteres comodín, como text/* . La aplicación de ejemplo agrega un tipo de MIME para image/svg+xml y comprime y sirve la imagen de banner banner.svg de ASP.NET Core.

using Microsoft.AspNetCore.ResponseCompression;
using ResponseCompressionSample;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
    options.Providers.Add<CustomCompressionProvider>();
    options.MimeTypes =
    ResponseCompressionDefaults.MimeTypes.Concat(
        new[] { "image/svg+xml" });
});

var app = builder.Build();

app.UseResponseCompression();

Adición del encabezado Vary

Al comprimir respuestas basadas en el encabezado de solicitud Accept-Encoding, puede haber versiones sin comprimir y múltiples versiones comprimidas de la respuesta. Para indicar a las memorias caché de cliente y proxy que existen varias versiones y deben almacenarse, el encabezado Vary se agrega con un valor Accept-Encoding. El middleware de respuesta agrega el encabezado Vary automáticamente cuando se comprime la respuesta.

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, use la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Problema de middleware cuando se encuentra detrás de un proxy inverso de Nginx

Cuando Nginx envía un proxy a una solicitud, se quita el encabezado Accept-Encoding. La eliminación del encabezado Accept-Encoding impide que el middleware de compresión de respuesta comprima la respuesta. Para más información, consulte NGINX: Compresión y descompresión. Se realiza un seguimiento de este problema mediante Determinar la compresión de tránsito para Nginx (dotnet/aspnetcore#5989).

Deshabilitación de la compresión dinámica de IIS

Para deshabilitar el módulo de compresión dinámica de IIS configurado en el nivel de servidor, consulte Deshabilitación de módulos de IIS.

Solución de problemas de compresión de respuesta

Use una herramienta como Firefox Browser Developer, que permite configurar el encabezado Accept-Encoding de la solicitud y estudiar los encabezados, el tamaño y el cuerpo de la respuesta. De forma predeterminada, el middleware de compresión de respuesta comprime las respuestas que cumplen las condiciones siguientes:

  • El encabezado Accept-Encoding está presente con un valor de br, gzip, * o una codificación personalizada que coincide con un proveedor de compresión personalizado. El valor no debe ser identity ni tener un valor de calidad (qvalue, q) igual a 0 (cero).
  • El tipo de MIME (Content-Type) debe estar configurado y debe coincidir con un tipo de MIME configurado en el ResponseCompressionOptions.
  • La solicitud no debe incluir el encabezado Content-Range.
  • La solicitud debe usar el protocolo no seguro (http), a menos que el protocolo seguro (https) esté configurado en las opciones de middleware de compresión de respuesta. Observe el peligro descrito anteriormente al habilitar la compresión de contenido segura.

Ejemplo implementado de Azure

La aplicación de ejemplo implementada en Azure tiene el siguiente archivo Program.cs:

using Microsoft.AspNetCore.ResponseCompression;
using ResponseCompressionSample;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
    options.Providers.Add<CustomCompressionProvider>();
    options.MimeTypes =
    ResponseCompressionDefaults.MimeTypes.Concat(
        new[] { "image/svg+xml" });
});

var app = builder.Build();

app.UseResponseCompression();

app.Map("/trickle", async (HttpResponse httpResponse) =>
{
    httpResponse.ContentType = "text/plain;charset=utf-8";

    for (int i = 0; i < 20; i++)
    {
        await httpResponse.WriteAsync("a");
        await httpResponse.Body.FlushAsync();
        await Task.Delay(TimeSpan.FromMilliseconds(50));
    }
});

app.Map("/testfile1kb.txt", () => Results.File(
    app.Environment.ContentRootFileProvider.GetFileInfo("testfile1kb.txt").PhysicalPath,
    "text/plain;charset=utf-8"));

app.Map("/banner.svg", () => Results.File(
    app.Environment.ContentRootFileProvider.GetFileInfo("banner.svg").PhysicalPath,
    "image/svg+xml;charset=utf-8"));

app.MapFallback(() => LoremIpsum.Text);

app.Run();

Recursos adicionales

Nota

Los vínculos de la documentación al origen de referencia de .NET cargan normalmente la rama predeterminada del repositorio, que representa el desarrollo actual para la próxima versión de .NET. Para seleccionar una etiqueta de una versión específica, use la lista desplegable Cambiar ramas o etiquetas. Para obtener más información, vea Procedimientos para seleccionar una etiqueta de versión de código fuente de ASP.NET Core (dotnet/AspNetCore.Docs #26205).

El ancho de banda de red es un recurso limitado. Reducir el tamaño de la respuesta suele aumentar la capacidad de respuesta de una aplicación, a menudo drásticamente. Una manera de reducir el tamaño de la carga útil es comprimir las respuestas de una aplicación.

Vea o descargue el código de ejemplo (cómo descargarlo)

Cuándo usar middleware de compresión de respuesta

Use tecnologías de compresión de respuesta basadas en servidor en IIS, Apache o Nginx. Es probable que el rendimiento del middleware no se corresponda con el de los módulos del servidor. {El servidor HTTP.sys y el servidor Kestrel no ofrecen actualmente soporte de compresión integrada.

Use el middleware de compresión de respuesta cuando:

Compresión de las respuestas

Normalmente, cualquier respuesta no comprimida de forma nativa puede beneficiarse de la compresión de respuesta. Las respuestas no comprimidas de forma nativa suelen incluir: CSS, JavaScript, HTML, XML y JSON. No debería comprimir activos comprimidos de forma nativa, como archivos PNG. Si intenta comprimir aún más una respuesta comprimida de forma nativa, es probable que cualquier pequeña reducción adicional en el tamaño y el tiempo de transmisión se vea eclipsada por el tiempo que se tardó en procesar la compresión. No comprima archivos menores que unos 150-1 000 bytes (según el contenido del archivo y la eficacia de la compresión). La sobrecarga de comprimir archivos pequeños puede producir un archivo comprimido mayor que el archivo sin comprimir.

Cuando un cliente puede procesar contenido comprimido, el cliente debe informar al servidor de sus funcionalidades enviando el encabezado Accept-Encoding con la solicitud. Cuando un servidor envía contenido comprimido, debe incluir información en el encabezado Content-Encoding sobre cómo se codifica la respuesta comprimida. Las designaciones de codificación de contenido admitidas por el middleware se muestran en la tabla siguiente.

Accept-Encoding valores de encabezado Middleware compatible Descripción
br Sí (predeterminado) Formato de datos comprimidos de Brotli
deflate No Formato de datos comprimidos DEFLATE
exi No Intercambio XML eficaz de W3C
gzip Formato de archivo Gzip
identity Identificador "Sin codificación": la respuesta no debe codificarse.
pack200-gzip No Formato de transferencia de red para archivos de Java
* Cualquier codificación de contenido disponible no solicitada explícitamente

Para más información, consulte la Lista oficial de codificación de contenido de IANA.

El middleware permite agregar proveedores de compresión adicionales para los valores de encabezado personalizados Accept-Encoding. Para más información, consulte Proveedores personalizados a continuación.

El middleware es capaz de reaccionar a la ponderación del valor de calidad (qvalue, q) cuando lo envía el cliente para priorizar los esquemas de compresión. Para más información, consulte RFC 9110: Accept-Encoding.

Los algoritmos de compresión están sujetos a un equilibrio entre la velocidad de compresión y la eficacia de la compresión. La eficacia en este contexto hace referencia al tamaño de la salida después de la compresión. El tamaño más pequeño se logra mediante la compresión más óptima.

Los encabezados implicados en la solicitud, envío, almacenamiento en caché y recepción de contenido comprimido se describen en la tabla siguiente.

Encabezado Rol
Accept-Encoding Enviado desde el cliente al servidor para indicar los esquemas de codificación de contenido aceptables para el cliente.
Content-Encoding Se envía desde el servidor al cliente para indicar la codificación del contenido en la carga.
Content-Length Cuando se produce la compresión, se elimina el encabezado Content-Length, ya que el contenido del cuerpo cambia cuando se comprime la respuesta.
Content-MD5 Cuando se produce la compresión, se elimina el encabezado Content-MD5, ya que el contenido del cuerpo ha cambiado y el hash ya no es válido.
Content-Type Especifica el tipo de MIME del contenido. Cada respuesta debe especificar su .Content-Type El middleware comprueba este valor para determinar si se debe comprimir la respuesta. El middleware especifica un conjunto de tipos de MIME predeterminados que puede codificar, pero puede reemplazar o agregar tipos de MIME.
Vary Cuando el servidor envía un valor de Accept-Encoding a los clientes y servidores proxy, el encabezado Vary indica al cliente o proxy que debe almacenar en caché (variar) las respuestas en función del valor del encabezado Accept-Encoding de la solicitud. El resultado de devolver contenido con el encabezado Vary: Accept-Encoding es que las respuestas comprimidas y sin comprimir se almacenan en caché por separado.

Explore las características de Middleware de compresión de respuestas con la aplicación de ejemplo. En el ejemplo se muestra:

  • La compresión de las respuestas de la aplicación mediante Gzip y proveedores de compresión personalizados.
  • Cómo agregar un tipo de MIME a la lista predeterminada de tipos de MIME para la compresión.

Configuración

En el código siguiente se muestra cómo habilitar el middleware de compresión de respuesta para los tipos y proveedores de compresión de MIME predeterminados (Brotli y Gzip):

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddResponseCompression();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseResponseCompression();
    }
}

Notas:

  • {Se debe llamar a app.UseResponseCompression antes de cualquier middleware que comprima respuestas. Para obtener más información, consulte Middleware de ASP.NET Core.
  • Use una herramienta como Fiddler o Firefox Browser Developer para establecer el encabezado Accept-Encoding de la solicitud y estudiar los encabezados, el tamaño y el cuerpo de la respuesta.

Envíe una solicitud a la aplicación de ejemplo sin el encabezado Accept-Encoding y observe que la respuesta no está comprimida. Los encabezados Content-Encoding y Vary están presentes en la respuesta.

Fiddler window showing result of a request without the Accept-Encoding header. The response isn't compressed.

Envíe una solicitud a la aplicación de ejemplo con el encabezado Accept-Encoding: br (compresión Brotli) y observe que la respuesta está comprimida. Los encabezados Content-Encoding y Vary están presentes en la respuesta.

Fiddler window showing result of a request with the Accept-Encoding header and a value of br. The Vary and Content-Encoding headers are added to the response. The response is compressed.

Proveedores

Proveedor de compresión Brotli

Use el BrotliCompressionProvider para comprimir las respuestas con el formato de datos comprimidos Brotli.

Si no se añaden explícitamente proveedores de compresión al CompressionProviderCollection:

  • El proveedor de compresión Brotli se agrega de manera predeterminada a la matriz de proveedores de compresión junto con el proveedor de compresión Gzip.
  • La compresión se establece de forma predeterminada en compresión Brotli cuando el formato de datos comprimidos Brotli es compatible con el cliente. Si Brotli no es compatible con el cliente, la compresión tiene como valor predeterminado Gzip cuando el cliente admite la compresión Gzip.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

El proveedor de compresión Brotli debe agregarse cuando se agregan explícitamente proveedores de compresión:

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes = 
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}

Establezca el nivel de compresión con BrotliCompressionProviderOptions. El proveedor de compresión Brotli utiliza de forma predeterminada el nivel de compresión más rápido (CompressionLevel.Fastest), que podría no producir la compresión más eficiente. Si se desea la compresión más eficiente, configure el middleware para una compresión óptima.

Nivel de compresión Descripción
CompressionLevel.Fastest La compresión debería completarse lo más rápidamente posible, incluso si la salida resultante no está comprimida de forma óptima.
CompressionLevel.NoCompression No debería realizarse ninguna compresión.
CompressionLevel.Optimal Las respuestas deben comprimirse de forma óptima, aunque la compresión tarde más tiempo en completarse.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

    services.Configure<BrotliCompressionProviderOptions>(options => 
    {
        options.Level = CompressionLevel.Fastest;
    });
}

Proveedor de compresión Gzip

Use el GzipCompressionProvider para comprimir respuestas con el formato de archivo Gzip.

Si no se añaden explícitamente proveedores de compresión al CompressionProviderCollection:

  • El proveedor de compresión Gzip se agrega de manera predeterminada a la matriz de proveedores de compresión junto con el proveedor de compresión Gzip.
  • La compresión se establece de forma predeterminada en compresión Brotli cuando el formato de datos comprimidos Brotli es compatible con el cliente. Si Brotli no es compatible con el cliente, la compresión tiene como valor predeterminado Gzip cuando el cliente admite la compresión Gzip.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

El proveedor de compresión Gzip debe agregarse cuando se agregan explícitamente proveedores de compresión:

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes = 
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}

Establezca el nivel de compresión con GzipCompressionProviderOptions. El proveedor de compresión Gzip utiliza de forma predeterminada el nivel de compresión más rápido (CompressionLevel.Fastest), que podría no producir la compresión más eficiente. Si se desea la compresión más eficiente, configure el middleware para una compresión óptima.

Nivel de compresión Descripción
CompressionLevel.Fastest La compresión debería completarse lo más rápidamente posible, incluso si la salida resultante no está comprimida de forma óptima.
CompressionLevel.NoCompression No debería realizarse ninguna compresión.
CompressionLevel.Optimal Las respuestas deben comprimirse de forma óptima, aunque la compresión tarde más tiempo en completarse.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

    services.Configure<GzipCompressionProviderOptions>(options => 
    {
        options.Level = CompressionLevel.Fastest;
    });
}

Proveedores personalizados

Cree implementaciones de compresión personalizadas con ICompressionProvider. EncodingName representa la codificación de contenido que genera ICompressionProvider. El middleware usa esta información para elegir el proveedor en función de la lista especificada en el encabezado Accept-Encoding de la solicitud.

Con la aplicación de ejemplo, el cliente envía una solicitud con el encabezado Accept-Encoding: mycustomcompression. El middleware usa la implementación de compresión personalizada y devuelve la respuesta con un encabezado Content-Encoding: mycustomcompression. El cliente debe poder descomprimir la codificación personalizada para que funcione una implementación de compresión personalizada.

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes = 
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}
public class CustomCompressionProvider : ICompressionProvider
{
    public string EncodingName => "mycustomcompression";
    public bool SupportsFlush => true;

    public Stream CreateStream(Stream outputStream)
    {
        // Create a custom compression stream wrapper here
        return outputStream;
    }
}

Envíe una solicitud a la aplicación de ejemplo con el encabezado Accept-Encoding: mycustomcompression y observe los encabezados de respuesta. Los encabezados Vary y Content-Encoding están presentes en la respuesta. El cuerpo de la respuesta (no se muestra) no se comprime en el ejemplo. No hay una implementación de compresión en la clase CustomCompressionProvider del ejemplo. Sin embargo, el ejemplo muestra dónde implementaría este algoritmo de compresión.

Fiddler window showing result of a request with the Accept-Encoding header and a value of mycustomcompression. The Vary and Content-Encoding headers are added to the response.

tipos MIME

El middleware especifica un conjunto predeterminado de tipos de MIME para la compresión:

  • application/javascript
  • application/json
  • application/xml
  • text/css
  • text/html
  • text/json
  • text/plain
  • text/xml

Reemplace o anexe tipos de MIME con las opciones de middleware de compresión de respuesta. Tenga en cuenta que no se admiten tipos de MIME con caracteres comodín, como text/* . La aplicación de ejemplo agrega un tipo de MIME para image/svg+xml y comprime y sirve la imagen de banner (banner.svg) de ASP.NET Core.

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression(options =>
    {
        options.Providers.Add<BrotliCompressionProvider>();
        options.Providers.Add<GzipCompressionProvider>();
        options.Providers.Add<CustomCompressionProvider>();
        options.MimeTypes = 
            ResponseCompressionDefaults.MimeTypes.Concat(
                new[] { "image/svg+xml" });
    });
}

Compresión con protocolo seguro

Las respuestas comprimidas a través de conexiones seguras pueden controlarse con la opción EnableForHttps, que está desactivada de forma predeterminada. El uso de compresión con páginas generadas dinámicamente puede provocar problemas de seguridad como los ataques de CRIME y BREACH.

Adición del encabezado Vary

Al comprimir las respuestas en función del encabezado Accept-Encoding, puede haber varias versiones comprimidas de la respuesta y una versión sin comprimir. Para indicar a las memorias caché de cliente y proxy que existen varias versiones y deben almacenarse, el encabezado Vary se agrega con un valor Accept-Encoding. En ASP.NET Core 2.0 o posterior, el middleware agrega el encabezado Vary automáticamente cuando se comprime la respuesta.

Problema de middleware cuando se encuentra detrás de un proxy inverso de Nginx

Cuando Nginx envía un proxy a una solicitud, se quita el encabezado Accept-Encoding. La eliminación del encabezado Accept-Encoding impide que el middleware comprima la respuesta. Para más información, consulte NGINX: Compresión y descompresión. Se realiza un seguimiento de este problema mediante Determinar la compresión de tránsito para Nginx (dotnet/aspnetcore#5989).

Trabajar con compresión dinámica de IIS

Si tiene un módulo de compresión dinámica de IIS activo configurado en el nivel de servidor que desea deshabilitar para una aplicación, deshabilite el módulo con una adición al archivo web.config. Para más información, vea Disabling IIS modules (Deshabilitación de módulos de IIS).

Solución de problemas

Use una herramienta como Fiddler o Firefox Browser Developer, que le permiten establecer el encabezado de solicitud Accept-Encoding y estudiar los encabezados de respuesta, el tamaño y el cuerpo. De forma predeterminada, el middleware de compresión de respuesta comprime las respuestas que cumplen las condiciones siguientes:

  • El encabezado Accept-Encoding está presente con un valor de br, gzip, * o una codificación personalizada que coincide con un proveedor de compresión personalizado que haya establecido. El valor no debe ser identity ni tener un valor de calidad (qvalue, q) igual a 0 (cero).
  • El tipo de MIME (Content-Type) debe estar configurado y debe coincidir con un tipo de MIME configurado en el ResponseCompressionOptions.
  • La solicitud no debe incluir el encabezado Content-Range.
  • La solicitud debe usar el protocolo no seguro (http), a menos que el protocolo seguro (https) esté configurado en las opciones de middleware de compresión de respuesta. Observe el peligro descrito anteriormente al habilitar la compresión de contenido segura.

Recursos adicionales