Compressione della risposta in ASP.NET Core

La larghezza di banda di rete è una risorsa limitata. La riduzione delle dimensioni della risposta aumenta in genere la velocità di risposta di un'app, spesso notevolmente. Un modo per ridurre le dimensioni del payload consiste nel comprimere le risposte di un'app.

Compressione con HTTPS

Le risposte compresse sulle connessioni sicure possono essere controllate con l'opzione EnableForHttps , che è disabilitata per impostazione predefinita a causa del rischio di sicurezza. L'uso della compressione con pagine generate in modo dinamico può esporre l'app agli CRIME attacchi e BREACH . CRIME gli attacchi e BREACH possono essere mitigati in ASP.NET Core con token antiforgery. Per altre informazioni, vedere Prevenire attacchi tramite richieste intersito false (XSRF/CSRF) in ASP.NET Core. Per informazioni sulla mitigazione degli BREACH attacchi, vedere Mitigazioni all'indirizzo http://www.breachattack.com/

Anche se EnableForHttps è disabilitato nell'app, IIS, IIS Express e app Azure Servizio può applicare gzip al server Web IIS. Quando si esaminano le intestazioni di risposta, prendere nota del valore server. Un valore di intestazione della risposta imprevisto content-encoding può essere il risultato del server Web e non della configurazione dell'app core ASP.NET.

Quando usare il middleware di compressione della risposta

Usare tecnologie di compressione delle risposte basate su server in IIS, Apache o Nginx. Le prestazioni del middleware di compressione delle risposte probabilmente non corrispondono a quella dei moduli del server. HTTP.sys server e Kestrel server non offrono attualmente supporto per la compressione predefinita.

Usare il middleware di compressione della risposta quando l'app è:

Compressione delle risposte

In genere, qualsiasi risposta non compressa in modo nativo può trarre vantaggio dalla compressione delle risposte. Le risposte non compresse in modo nativo includono in genere CSS, JavaScript, HTML, XML e JSON. Non comprimere asset compressi in modo nativo, ad esempio file PNG. Quando si tenta di comprimere ulteriormente una risposta compressa in modo nativo, è probabile che qualsiasi piccola riduzione aggiuntiva delle dimensioni e del tempo di trasmissione venga oscurata dal tempo necessario per elaborare la compressione. Non comprimere i file di dimensioni inferiori a circa 150-1000 byte, a seconda del contenuto del file e dell'efficienza della compressione. Il sovraccarico della compressione di file di piccole dimensioni può produrre un file compresso più grande del file non compresso.

Quando un client può elaborare contenuto compresso, il client deve informare il server delle relative funzionalità inviando l'intestazione Accept-Encoding con la richiesta. Quando un server invia contenuto compresso, deve includere informazioni nell'intestazione Content-Encoding sulla modalità di codifica della risposta compressa. Le designazioni di codifica del contenuto supportate dal middleware di compressione delle risposte sono illustrate nella tabella seguente.

Accept-Encoding valori di intestazione Middleware supportato Descrizione
br Sì (impostazione predefinita) Formato di dati compressi Brotli
deflate No Formato di dati compressi DEFLATE
exi No Interscambio XML efficiente W3C
gzip Formato di file Gzip
identity Identificatore "Nessuna codifica": la risposta non deve essere codificata.
pack200-gzip No Formato trasferimento di rete per archivi Java
* Qualsiasi codifica del contenuto disponibile non richiesta in modo esplicito

Per altre informazioni, vedere l'elenco ufficiale di codifica del contenuto di IANA.

Il middleware di compressione delle risposte consente di aggiungere provider di compressione aggiuntivi per i valori di intestazione personalizzati Accept-Encoding . Per altre informazioni, vedere Provider personalizzati in questo articolo.

Il middleware di compressione della risposta è in grado di reagire al peso del valore di qualità (qvalue, q) quando inviato dal client per classificare in ordine di priorità gli schemi di compressione. Per altre informazioni, vedere RFC 9110: Accept-Encoding.

Gli algoritmi di compressione sono soggetti a un compromesso tra la velocità di compressione e l'efficacia della compressione. L'efficacia in questo contesto si riferisce alle dimensioni dell'output dopo la compressione. La dimensione più piccola viene ottenuta dalla compressione ottimale.

Le intestazioni coinvolte nella richiesta, nell'invio, nella memorizzazione nella cache e nella ricezione di contenuto compresso sono descritte nella tabella seguente.

Intestazione Ruolo
Accept-Encoding Inviato dal client al server per indicare gli schemi di codifica del contenuto accettabili per il client.
Content-Encoding Inviato dal server al client per indicare la codifica del contenuto nel payload.
Content-Length Quando si verifica la compressione, l'intestazione Content-Length viene rimossa, poiché il contenuto del corpo cambia quando la risposta viene compressa.
Content-MD5 Quando si verifica la compressione, l'intestazione Content-MD5 viene rimossa, poiché il contenuto del corpo è stato modificato e l'hash non è più valido.
Content-Type Specifica il tipo MIME del contenuto. Ogni risposta deve specificare il relativo Content-Typeoggetto . Il middleware di compressione della risposta controlla questo valore per determinare se la risposta deve essere compressa. Il middleware di compressione della risposta specifica un set di tipi MIME predefiniti che può codificare e può essere sostituito o aggiunto.
Vary Quando inviato dal server con un valore a Accept-Encoding client e proxy, l'intestazione Vary indica al client o al proxy che deve memorizzare nella cache (variare) le risposte in base al valore dell'intestazione Accept-Encoding della richiesta. Il risultato della restituzione del contenuto con l'intestazione Vary: Accept-Encoding è che le risposte compresse e non compresse vengono memorizzate nella cache separatamente.

Esplorare le funzionalità del middleware di compressione della risposta con l'app di esempio. L'esempio illustra:

  • Compressione delle risposte dell'app tramite Gzip e provider di compressione personalizzati.
  • Come aggiungere un tipo MIME all'elenco predefinito di tipi MIME per la compressione.
  • Come aggiungere un provider di compressione delle risposte personalizzato.

Impostazione

Il codice seguente illustra come abilitare il middleware di compressione della risposta per i tipi MIME e i provider di compressione predefiniti (Brotli e 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();

Note:

  • L'impostazione su EnableForHttpstrue è un rischio per la sicurezza. Per altre informazioni, vedere Compressione con HTTPS in questo articolo.
  • app.UseResponseCompression deve essere chiamato prima di qualsiasi middleware che comprima le risposte. Per altre informazioni, vedere Middleware ASP.NET Core.
  • Usare uno strumento come Firefox Browser Developer per impostare l'intestazione della Accept-Encoding richiesta ed esaminare le intestazioni, le dimensioni e il corpo della risposta.

Inviare una richiesta all'app di esempio senza l'intestazione Accept-Encoding e osservare che la risposta non è compressa. L'intestazione Content-Encoding non è presente nell'insieme Response Headers.

Ad esempio, in Firefox Developer:

  • Selezionare la scheda rete.
  • Fare clic con il pulsante destro del mouse sulla richiesta nell'elenco Richieste di rete e selezionare Modifica e invia di nuovo
  • Passare Accept-Encoding: da gzip, deflate, br a none.
  • Selezionare Invia.

Inviare una richiesta all'app di esempio con un browser usando gli strumenti di sviluppo e osservare che la risposta è compressa. Le Content-Encoding intestazioni e Vary sono presenti nella risposta.

Provider

Provider di compressione Brotli e Gzip

BrotliCompressionProvider Usare per comprimere le risposte con il formato di dati compresso Brotli.

Se nessun provider di compressione viene aggiunto in modo esplicito a CompressionProviderCollection:

  • Il provider di compressione Brotli e il provider di compressione Gzip vengono aggiunti per impostazione predefinita alla matrice di provider di compressione.
  • Per impostazione predefinita, la compressione Brotli è supportata dal client quando il formato di dati compressi Brotli è supportato dal client. Se Brotli non è supportato dal client, l'impostazione predefinita della compressione è Gzip quando il client supporta la compressione Gzip.

Nota

I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

Quando viene aggiunto un provider di compressione, gli altri provider non vengono aggiunti. Ad esempio, se il provider di compressione Gzip è l'unico provider aggiunto in modo esplicito, non vengono aggiunti altri provider di compressione.

Il codice seguente:

  • Abilita la compressione delle risposte per le richieste HTTPS.
  • Aggiunge i provider di compressione delle risposte Brotli e 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();

Impostare il livello di compressione con BrotliCompressionProviderOptions e GzipCompressionProviderOptions. Per impostazione predefinita, i provider di compressione Brotli e Gzip sono il livello di compressione più veloce, CompressionLevel.Fastest, che potrebbe non produrre la compressione più efficiente. Se si desidera una compressione più efficiente, configurare il middleware di compressione della risposta per una compressione ottimale.

Vedere CompressionLevel Enum per i valori che indicano se un'operazione di compressione evidenzia la velocità o le dimensioni della compressione.

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();

Provider personalizzati

Creare implementazioni di compressione personalizzate con ICompressionProvider. Rappresenta EncodingName la codifica del contenuto che produce.ICompressionProvider Il middleware di compressione della risposta usa queste informazioni per scegliere il provider in base all'elenco specificato nell'intestazione Accept-Encoding della richiesta.

Le richieste all'app di esempio con l'intestazione Accept-Encoding: mycustomcompression restituiscono una risposta con un'intestazione Content-Encoding: mycustomcompression . Il client deve essere in grado di decomprimere la codifica personalizzata per consentire il funzionamento di un'implementazione di compressione personalizzata.

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 il codice precedente, il corpo della risposta non viene compresso dall'esempio. Tuttavia, l'esempio mostra dove implementare un algoritmo di compressione personalizzato.

MIME (tipi)

Il middleware di compressione della risposta specifica un set predefinito di tipi MIME per la compressione. Per un elenco completo dei tipi MIME supportati, vedere il codice sorgente.

Nota

I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

Sostituire o aggiungere tipi MIME con ResponseCompressionOptions.MimeTypes. Si noti che i tipi MIME con caratteri jolly, ad esempio text/* non sono supportati. L'app di esempio aggiunge un tipo MIME per image/svg+xml e comprime e gestisce l'immagine banner ASP.NET Core banner.svg.

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();

Aggiunta dell'intestazione Vary

Quando si comprimono le risposte in base all'intestazione della Accept-Encoding richiesta, è possibile decomprimere e più versioni compresse della risposta. Per indicare alla cache client e proxy che esistono più versioni e devono essere archiviate, l'intestazione Vary viene aggiunta con un Accept-Encoding valore. Il middleware di risposta aggiunge automaticamente l'intestazione Vary quando la risposta viene compressa.

Nota

I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

Problema del middleware quando si è dietro un proxy inverso Nginx

Quando una richiesta viene inoltrata tramite proxy da Nginx, l'intestazione Accept-Encoding viene rimossa. La rimozione dell'intestazione Accept-Encoding impedisce al middleware di compressione della risposta di comprimere la risposta. Per altre informazioni, vedere NGINX: Compressione e decompressione. Questo problema viene rilevato dalla figura della compressione pass-through per Nginx (dotnet/aspnetcore#5989).

Disabilitazione della compressione dinamica IIS

Per disabilitare IIS Dynamic Compression Module configurato a livello di server, vedere Disabilitazione dei moduli IIS.

Risolvere i problemi di compressione delle risposte

Usare uno strumento come Firefox Browser Developer, che consente di impostare l'intestazione della Accept-Encoding richiesta e studiare le intestazioni, le dimensioni e il corpo della risposta. Per impostazione predefinita, il middleware di compressione della risposta comprime le risposte che soddisfano le condizioni seguenti:

  • L'intestazione Accept-Encoding è presente con un valore di brcodifica personalizzata , gzip, *o corrispondente a un provider di compressione personalizzato. Il valore non deve essere identity o avere un valore di qualità (qvalue, q) impostato su 0 (zero).
  • Il tipo MIME (Content-Type) deve essere impostato e deve corrispondere a un tipo MIME configurato in ResponseCompressionOptions.
  • La richiesta non deve includere l'intestazione Content-Range .
  • La richiesta deve usare il protocollo non sicuro (http), a meno che non sia configurato il protocollo sicuro (https) nelle opzioni middleware di compressione della risposta. Si noti il pericolo descritto in precedenza quando si abilita la compressione sicura del contenuto.

Esempio distribuito di Azure

L'app di esempio distribuita in Azure include il file seguente 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();

Risorse aggiuntive

Nota

I collegamenti della documentazione all'origine del riferimento .NET in genere caricano il ramo predefinito del repository, che rappresenta lo sviluppo corrente per la versione successiva di .NET. Per selezionare un tag per una versione specifica, usare l'elenco a discesa Switch branches or tags. Per altre informazioni, vedere How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Come selezionare un tag di versione del codice sorgente di ASP.NET - dotnet/AspNetCore.Docs #26205).

La larghezza di banda di rete è una risorsa limitata. La riduzione delle dimensioni della risposta aumenta in genere la velocità di risposta di un'app, spesso notevolmente. Un modo per ridurre le dimensioni del payload consiste nel comprimere le risposte di un'app.

Visualizzare o scaricare il codice di esempio (procedura per il download)

Quando usare il middleware di compressione della risposta

Usare tecnologie di compressione delle risposte basate su server in IIS, Apache o Nginx. Le prestazioni del middleware probabilmente non corrispondono a quella dei moduli server. HTTP.sys server e Kestrel server non offrono attualmente supporto per la compressione predefinita.

Usare il middleware di compressione della risposta quando si è:

Compressione delle risposte

In genere, qualsiasi risposta non compressa in modo nativo può trarre vantaggio dalla compressione delle risposte. Le risposte non compresse in modo nativo in genere includono: CSS, JavaScript, HTML, XML e JSON. Non è consigliabile comprimere asset compressi in modo nativo, ad esempio file PNG. Se si tenta di comprimere ulteriormente una risposta compressa in modo nativo, è probabile che qualsiasi piccola riduzione aggiuntiva delle dimensioni e del tempo di trasmissione venga oscurata dal tempo necessario per elaborare la compressione. Non comprimere i file di dimensioni inferiori a circa 150-1000 byte (a seconda del contenuto del file e dell'efficienza della compressione). Il sovraccarico della compressione di file di piccole dimensioni può produrre un file compresso più grande del file non compresso.

Quando un client può elaborare contenuto compresso, il client deve informare il server delle relative funzionalità inviando l'intestazione Accept-Encoding con la richiesta. Quando un server invia contenuto compresso, deve includere informazioni nell'intestazione Content-Encoding sulla modalità di codifica della risposta compressa. Le designazioni di codifica del contenuto supportate dal middleware sono illustrate nella tabella seguente.

Accept-Encoding valori di intestazione Middleware supportato Descrizione
br Sì (impostazione predefinita) Formato di dati compressi Brotli
deflate No Formato di dati compressi DEFLATE
exi No Interscambio XML efficiente W3C
gzip Formato di file Gzip
identity Identificatore "Nessuna codifica": la risposta non deve essere codificata.
pack200-gzip No Formato trasferimento di rete per archivi Java
* Qualsiasi codifica del contenuto disponibile non richiesta in modo esplicito

Per altre informazioni, vedere l'elenco ufficiale di codifica del contenuto di IANA.

Il middleware consente di aggiungere altri provider di compressione per i valori di intestazione personalizzati Accept-Encoding . Per altre informazioni, vedere Provider personalizzati di seguito.

Il middleware è in grado di reagire al peso del valore di qualità (qvalue, q) quando inviato dal client per classificare in ordine di priorità gli schemi di compressione. Per altre informazioni, vedere RFC 9110: Accept-Encoding.

Gli algoritmi di compressione sono soggetti a un compromesso tra la velocità di compressione e l'efficacia della compressione. L'efficacia in questo contesto si riferisce alle dimensioni dell'output dopo la compressione. La dimensione più piccola è ottenuta dalla compressione più ottimale .

Le intestazioni coinvolte nella richiesta, nell'invio, nella memorizzazione nella cache e nella ricezione di contenuto compresso sono descritte nella tabella seguente.

Intestazione Ruolo
Accept-Encoding Inviato dal client al server per indicare gli schemi di codifica del contenuto accettabili per il client.
Content-Encoding Inviato dal server al client per indicare la codifica del contenuto nel payload.
Content-Length Quando si verifica la compressione, l'intestazione Content-Length viene rimossa, poiché il contenuto del corpo cambia quando la risposta viene compressa.
Content-MD5 Quando si verifica la compressione, l'intestazione Content-MD5 viene rimossa, poiché il contenuto del corpo è stato modificato e l'hash non è più valido.
Content-Type Specifica il tipo MIME del contenuto. Ogni risposta deve specificare il relativo Content-Typeoggetto . Il middleware controlla questo valore per determinare se la risposta deve essere compressa. Il middleware specifica un set di tipi MIME predefiniti che può codificare, ma è possibile sostituire o aggiungere tipi MIME.
Vary Quando inviato dal server con un valore a Accept-Encoding client e proxy, l'intestazione Vary indica al client o al proxy che deve memorizzare nella cache (variare) le risposte in base al valore dell'intestazione Accept-Encoding della richiesta. Il risultato della restituzione del contenuto con l'intestazione Vary: Accept-Encoding è che le risposte compresse e non compresse vengono memorizzate nella cache separatamente.

Esplorare le funzionalità del middleware di compressione della risposta con l'app di esempio. L'esempio illustra:

  • Compressione delle risposte dell'app tramite Gzip e provider di compressione personalizzati.
  • Come aggiungere un tipo MIME all'elenco predefinito di tipi MIME per la compressione.

Impostazione

Il codice seguente illustra come abilitare il middleware di compressione della risposta per i tipi MIME e i provider di compressione predefiniti (Brotli e Gzip):

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

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

Note:

  • app.UseResponseCompression deve essere chiamato prima di qualsiasi middleware che comprima le risposte. Per altre informazioni, vedere Middleware ASP.NET Core.
  • Usare uno strumento come Fiddler, Firefox Browser Developer per impostare l'intestazione della Accept-Encoding richiesta e studiare le intestazioni, le dimensioni e il corpo della risposta.

Inviare una richiesta all'app di esempio senza l'intestazione Accept-Encoding e osservare che la risposta non è compressa. Le Content-Encoding intestazioni e Vary non sono presenti nella risposta.

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

Inviare una richiesta all'app di esempio con l'intestazione Accept-Encoding: br (compressione Brotli) e osservare che la risposta è compressa. Le Content-Encoding intestazioni e Vary sono presenti nella risposta.

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.

Provider

Provider di compressione Brotli

BrotliCompressionProvider Usare per comprimere le risposte con il formato di dati compresso Brotli.

Se nessun provider di compressione viene aggiunto in modo esplicito a CompressionProviderCollection:

  • Il provider di compressione Brotli viene aggiunto per impostazione predefinita alla matrice di provider di compressione insieme al provider di compressione Gzip.
  • Per impostazione predefinita, la compressione Brotli è supportata dal client quando il formato di dati compressi Brotli è supportato dal client. Se Brotli non è supportato dal client, l'impostazione predefinita della compressione è Gzip quando il client supporta la compressione Gzip.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

Il provider di compressione Brotli deve essere aggiunto quando vengono aggiunti in modo esplicito provider di compressione:

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" });
    });
}

Impostare il livello di compressione con BrotliCompressionProviderOptions. Il provider di compressione Brotli usa per impostazione predefinita il livello di compressione più veloce (CompressionLevel.Fastest), che potrebbe non produrre la compressione più efficiente. Se si desidera una compressione più efficiente, configurare il middleware per una compressione ottimale.

Compression Level Descrizione
CompressionLevel.Fastest La compressione deve essere completata il più rapidamente possibile, anche se l'output risultante non è compresso in modo ottimale.
CompressionLevel.NoCompression Non deve essere eseguita alcuna compressione.
CompressionLevel.Optimal Le risposte devono essere compresse in modo ottimale, anche se il completamento della compressione richiede più tempo.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

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

Provider di compressione Gzip

GzipCompressionProvider Usare per comprimere le risposte con il formato di file Gzip.

Se nessun provider di compressione viene aggiunto in modo esplicito a CompressionProviderCollection:

  • Il provider di compressione Gzip viene aggiunto per impostazione predefinita alla matrice di provider di compressione insieme al provider di compressione Brotli.
  • Per impostazione predefinita, la compressione Brotli è supportata dal client quando il formato di dati compressi Brotli è supportato dal client. Se Brotli non è supportato dal client, l'impostazione predefinita della compressione è Gzip quando il client supporta la compressione Gzip.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

Il provider di compressione Gzip deve essere aggiunto quando vengono aggiunti in modo esplicito provider di compressione:

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" });
    });
}

Impostare il livello di compressione con GzipCompressionProviderOptions. Il provider di compressione Gzip usa per impostazione predefinita il livello di compressione più veloce (CompressionLevel.Fastest), che potrebbe non produrre la compressione più efficiente. Se si desidera una compressione più efficiente, configurare il middleware per una compressione ottimale.

Compression Level Descrizione
CompressionLevel.Fastest La compressione deve essere completata il più rapidamente possibile, anche se l'output risultante non è compresso in modo ottimale.
CompressionLevel.NoCompression Non deve essere eseguita alcuna compressione.
CompressionLevel.Optimal Le risposte devono essere compresse in modo ottimale, anche se il completamento della compressione richiede più tempo.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

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

Provider personalizzati

Creare implementazioni di compressione personalizzate con ICompressionProvider. Rappresenta EncodingName la codifica del contenuto che produce.ICompressionProvider Il middleware usa queste informazioni per scegliere il provider in base all'elenco specificato nell'intestazione Accept-Encoding della richiesta.

Usando l'app di esempio, il client invia una richiesta con l'intestazione Accept-Encoding: mycustomcompression . Il middleware usa l'implementazione della compressione personalizzata e restituisce la risposta con un'intestazione Content-Encoding: mycustomcompression . Il client deve essere in grado di decomprimere la codifica personalizzata per consentire il funzionamento di un'implementazione di compressione personalizzata.

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

Inviare una richiesta all'app di esempio con l'intestazione Accept-Encoding: mycustomcompression e osservare le intestazioni di risposta. Le Vary intestazioni e Content-Encoding sono presenti nella risposta. Il corpo della risposta (non visualizzato) non è compresso dall'esempio. Non esiste un'implementazione della compressione nella CustomCompressionProvider classe dell'esempio. Tuttavia, l'esempio mostra dove implementare tale algoritmo di compressione.

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.

MIME (tipi)

Il middleware specifica un set predefinito di tipi MIME per la compressione:

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

Sostituire o aggiungere tipi MIME con le opzioni middleware di compressione della risposta. Si noti che i tipi MIME con caratteri jolly, ad esempio text/* non sono supportati. L'app di esempio aggiunge un tipo MIME per image/svg+xml e comprime e gestisce l'immagine banner ASP.NET Core (banner.svg).

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" });
    });
}

Compressione con protocollo sicuro

Le risposte compresse sulle connessioni sicure possono essere controllate con l'opzione EnableForHttps , che è disabilitata per impostazione predefinita. L'uso della compressione con pagine generate in modo dinamico può causare problemi di sicurezza, ad CRIME esempio gli attacchi e BREACH .

Aggiunta dell'intestazione Vary

Quando si comprimono le risposte in base all'intestazione Accept-Encoding , esistono potenzialmente più versioni compresse della risposta e una versione non compressa. Per indicare alla cache client e proxy che esistono più versioni e devono essere archiviate, l'intestazione Vary viene aggiunta con un Accept-Encoding valore. In ASP.NET Core 2.0 o versione successiva, il middleware aggiunge automaticamente l'intestazione Vary quando la risposta viene compressa.

Problema del middleware quando si è dietro un proxy inverso Nginx

Quando una richiesta viene inoltrata tramite proxy da Nginx, l'intestazione Accept-Encoding viene rimossa. La rimozione dell'intestazione Accept-Encoding impedisce al middleware di comprimere la risposta. Per altre informazioni, vedere NGINX: Compressione e decompressione. Questo problema viene rilevato dalla figura della compressione pass-through per Nginx (dotnet/aspnetcore#5989).

Utilizzo della compressione dinamica IIS

Se si dispone di un modulo di compressione dinamica IIS attivo configurato a livello di server che si vuole disabilitare per un'app, disabilitare il modulo con un'aggiunta al file web.config . Per altre informazioni, vedere Disabling IIS modules (Disabilitazione di moduli IIS).

Risoluzione dei problemi

Usare uno strumento come Fiddler o Firefox Browser Developer, che consente di impostare l'intestazione della Accept-Encoding richiesta e studiare le intestazioni, le dimensioni e il corpo della risposta. Per impostazione predefinita, il middleware di compressione della risposta comprime le risposte che soddisfano le condizioni seguenti:

  • L'intestazione Accept-Encoding è presente con il valore br, gzip, *o la codifica personalizzata che corrisponde a un provider di compressione personalizzato stabilito. Il valore non deve essere identity o avere un valore di qualità (qvalue, q) impostato su 0 (zero).
  • Il tipo MIME (Content-Type) deve essere impostato e deve corrispondere a un tipo MIME configurato in ResponseCompressionOptions.
  • La richiesta non deve includere l'intestazione Content-Range .
  • La richiesta deve usare il protocollo non sicuro (http), a meno che non sia configurato il protocollo sicuro (https) nelle opzioni middleware di compressione della risposta. Si noti il pericolo descritto in precedenza quando si abilita la compressione sicura del contenuto.

Risorse aggiuntive