Komprese odpovědí v ASP.NET Core

Šířka pásma sítě je omezený prostředek. Zmenšení velikosti odpovědi obvykle zvyšuje rychlost odezvy aplikace, často výrazně. Jedním ze způsobů, jak snížit velikost datové části, je komprimovat odpovědi aplikace.

Komprese pomocí PROTOKOLU HTTPS

Komprimované odpovědi přes zabezpečená připojení je možné řídit pomocí EnableForHttps možnosti, která je ve výchozím nastavení zakázaná z důvodu rizika zabezpečení. Použití komprese s dynamicky generovanými stránkami může aplikaci vystavit CRIME a BREACH útoky. CRIME útoky BREACH je možné zmírnit v ASP.NET Core s antiforgery tokeny. Další informace najdete v tématu Prevence útoků založených na padělání žádosti posílané mezi weby (XSRF/CSRF) v ASP.NET Core. Informace o zmírnění BREACH útoků najdete v tématu zmírnění rizik na adrese <>/0>.http://www.breachattack.com/

I když EnableForHttps je v aplikaci zakázána služba IIS, IIS Express a Aplikace Azure Service, může použít gzip na webovém serveru SLUŽBY IIS. Při kontrole hlaviček odpovědí si poznamenejte hodnotu Serveru . Neočekávaná content-encoding hodnota hlavičky odpovědi může být výsledkem webového serveru, a ne konfigurace aplikace ASP.NET Core.

Kdy použít middleware pro kompresi odpovědí

Používejte technologie komprese odpovědí založené na serveru ve službě IIS, Apache nebo Nginx. Výkon middlewaru komprese odpovědí pravděpodobně neodpovídá výkonu modulů serveru. HTTP.sys server a Kestrel server v současné době nenabízí integrovanou podporu komprese.

Middleware pro kompresi odpovědí použijte, když je aplikace:

Komprese odpovědí

Každá odpověď, která není nativně komprimovaná, může obvykle těžit z komprese odpovědí. Mezi odpovědi, které nejsou nativně komprimované, obvykle patří CSS, JavaScript, HTML, XML a JSON. Nekomprimujte nativně komprimované prostředky, například soubory PNG. Při pokusu o další komprimaci nativně komprimované odpovědi se jakékoli malé zmenšení velikosti a doby přenosu pravděpodobně přetlačí časem potřebným ke zpracování komprese. Nekomprimujte soubory menší než přibližně 150–1000 bajtů v závislosti na obsahu souboru a efektivitě komprese. Režie komprimace malých souborů může způsobit komprimovaný soubor větší než nekomprimovaný soubor.

Když klient může zpracovávat komprimovaný obsah, musí klient informovat server o jeho schopnostech odesláním Accept-Encoding hlavičky s požadavkem. Když server odesílá komprimovaný obsah, musí obsahovat informace v Content-Encoding hlavičce o tom, jak je komprimovaná odpověď kódována. V následující tabulce jsou uvedena označení kódování obsahu podporovaná middlewarem komprese odpovědí.

Accept-Encoding hodnoty záhlaví Podporovaný middleware Popis
br Ano (výchozí) Komprimovaný formát dat Brotli
deflate No DEFLATE komprimovaný formát dat
exi No W3C Efektivní výměna XML
gzip Ano Formát souboru Gzip
identity Ano Identifikátor Bez kódování: Odpověď nesmí být zakódována.
pack200-gzip No Formát přenosu sítě pro archivy Java
* Ano Jakékoli kódování dostupného obsahu, které není explicitně požadováno

Další informace najdete v oficiálním seznamu kódování obsahu IANA.

Middleware komprese odpovědí umožňuje přidat další zprostředkovatele komprese pro vlastní Accept-Encoding hodnoty hlaviček. Další informace naleznete v části Vlastní zprostředkovatelé v tomto článku.

Middleware komprese odpovědí je schopen reagovat na kvalitu hodnoty (qvalue, q) váhy při odesílání klientem kvůli stanovení priority schémat komprese. Další informace naleznete v dokumentu RFC 9110: Accept-Encoding.

Algoritmy komprese podléhají kompromisu mezi rychlostí komprese a účinností komprese. Účinnost v tomto kontextu odkazuje na velikost výstupu po kompresi. Nejmenší velikost dosáhne optimální komprese.

Hlavičky, které se týkají vyžádání, odesílání, ukládání do mezipaměti a příjmu komprimovaného obsahu, jsou popsány v následující tabulce.

Hlavička Role
Accept-Encoding Odesláno z klienta na server, aby indikuje schémata kódování obsahu přijatelná pro klienta.
Content-Encoding Odesláno ze serveru klientovi, které označuje kódování obsahu v datové části.
Content-Length Když dojde k kompresi, Content-Length záhlaví se odebere, protože obsah těla se změní při komprimaci odpovědi.
Content-MD5 Když dojde ke kompresi, Content-MD5 záhlaví se odebere, protože se změnil základní obsah a hodnota hash už není platná.
Content-Type Určuje typ MIME obsahu. Každá odpověď by měla být zadána .Content-Type Middleware komprese odpovědi zkontroluje tuto hodnotu a určí, jestli má být odpověď komprimována. Middleware komprese odpovědí určuje sadu výchozích typů MIME, které může kódovat, a mohou být nahrazeny nebo přidány.
Vary Když server odešle hodnotu Accept-Encoding klientům a proxy serverům, Vary hlavička značí klientovi nebo proxy serveru, že by se měly ukládat odpovědi (různé) v závislosti na hodnotě Accept-Encoding hlavičky požadavku. Výsledkem vrácení obsahu s hlavičkou Vary: Accept-Encoding je, že komprimované i nekomprimované odpovědi se ukládají do mezipaměti samostatně.

Prozkoumejte funkce middlewaru pro kompresi odpovědí pomocí ukázkové aplikace. Ukázka ukazuje:

  • Komprese odpovědí aplikace pomocí Gzip a vlastních poskytovatelů komprese.
  • Jak přidat typ MIME do výchozího seznamu typů MIME pro kompresi.
  • Postup přidání vlastního zprostředkovatele komprese odpovědí

Konfigurace

Následující kód ukazuje, jak povolit middleware Komprese odpovědí pro výchozí typy MIME a zprostředkovatele komprese (Brotli a 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();

Poznámky:

Odešlete požadavek do ukázkové aplikace bez hlavičky Accept-Encoding a všimněte si, že odpověď není dekomprimovaná. Hlavička Content-Encoding není v kolekci Headers odpovědi.

Například ve Firefoxu Developer:

  • Vyberte kartu sítě.
  • Klikněte pravým tlačítkem myši na žádost v seznamu síťových požadavků a vyberte Upravit a znovu odeslat.
  • Změnit Accept-Encoding: z gzip, deflate, br na none.
  • Vyberte Odeslat.

Odešlete žádost do ukázkové aplikace pomocí prohlížeče pomocí vývojářských nástrojů a všimněte si, že odpověď je komprimovaná. Vary V Content-Encoding odpovědi jsou k dispozici hlavičky.

Poskytovatelé

Poskytovatelé komprese Brotli a Gzip

BrotliCompressionProvider Slouží ke komprimaci odpovědí pomocí komprimovaného datového formátu Brotli.

Pokud nejsou do CompressionProviderCollection: explicitně přidáni žádní poskytovatelé komprese:

  • Poskytovatel komprese Brotli a zprostředkovatel komprese Gzip jsou ve výchozím nastavení přidány do pole zprostředkovatelů komprese.
  • Komprese je ve výchozím nastavení brotli komprese, pokud klient podporuje komprimovaný datový formát Brotli. Pokud klient brotli nepodporuje, komprese se ve výchozím nastavení nastaví na Gzip, pokud klient podporuje kompresi Gzip.

Poznámka:

Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Když přidáte zprostředkovatele komprese, ostatní zprostředkovatelé se nepřidají. Pokud je například zprostředkovatel komprese Gzip jediným přidaným zprostředkovatelem, nepřidají se žádní další zprostředkovatelé komprese.

Následující kód:

  • Povolí kompresi odpovědí pro požadavky HTTPS.
  • Přidá poskytovatele komprese odpovědí Brotli a 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();

Nastavte úroveň komprese s BrotliCompressionProviderOptions a GzipCompressionProviderOptions. Poskytovatelé komprese Brotli a Gzip mají výchozí hodnotu na nejrychlejší úroveň komprese CompressionLevel.Fastest, která nemusí produkovat nejúčinnější kompresi. Pokud je požadovaná nejúčinnější komprese, nakonfigurujte middleware komprese odpovědí pro optimální kompresi.

Viz CompressionLevel Výčtu pro hodnoty, které označují, zda operace komprese zvýrazňuje rychlost nebo velikost komprese.

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

Vlastní poskytovatelé

Vytváření vlastních implementací komprese pomocí ICompressionProvider. Představuje EncodingName kódování obsahu, které se tím ICompressionProvider vytvoří. Middleware komprese odpovědí používá tyto informace k výběru poskytovatele na základě seznamu zadaného v Accept-Encoding hlavičce požadavku.

Požadavky na ukázkovou aplikaci s Accept-Encoding: mycustomcompression hlavičkou vrátí odpověď s hlavičkou Content-Encoding: mycustomcompression . Aby vlastní implementace komprese fungovala, musí být klient schopen dekomprimovat vlastní kódování.

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

S předchozím kódem není tělo odpovědi komprimované ukázkou. Ukázka ale ukazuje, kde implementovat vlastní algoritmus komprese.

typy MIME

Middleware komprese odpovědí určuje výchozí sadu typů MIME pro kompresi. Úplný seznam podporovaných typů MIME najdete ve zdrojovém kódu.

Poznámka:

Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Nahraďte nebo připojte typy MIME .ResponseCompressionOptions.MimeTypes Všimněte si, že typy MIME se zástupnými znaménkami, například text/* se nepodporují. Ukázková aplikace přidá typ MIME pro image/svg+xml a komprimuje a obsluhuje obrázek banneru 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();

Přidání záhlaví Vary

Při komprimaci odpovědí na Accept-Encoding základě hlavičky požadavku mohou být nekomprimované a více komprimovaných verzí odpovědi. Aby bylo možné dát klientovi a proxy mezipaměti pokyn, aby existovalo více verzí a mělo by se uložit, Vary přidá se hlavička s Accept-Encoding hodnotou. Middleware odpovědi přidá hlavičku Vary automaticky při komprimaci odpovědi.

Poznámka:

Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Problém s middlewarem za reverzním proxy serverem Nginx

Když Nginx proxiuje požadavek, hlavička Accept-Encoding se odebere. Odebrání hlavičky Accept-Encoding brání middlewaru komprese odpovědí v komprimaci odpovědi. Další informace naleznete v tématu NGINX: Komprese a dekomprese. Tento problém sleduje předávací komprese Nginx (dotnet/aspnetcore#5989).

Zakázání dynamické komprese služby IIS

Pokud chcete zakázat modul dynamické komprese služby IIS nakonfigurovaný na úrovni serveru, přečtěte si téma Zakázání modulů SLUŽBY IIS.

Řešení potíží s kompresí odpovědí

Použijte nástroj, jako je Firefox Browser Developer, který umožňuje nastavit hlavičku Accept-Encoding požadavku a studovat hlavičky, velikost a text odpovědi. Middleware komprese odpovědí ve výchozím nastavení komprimuje odpovědi, které splňují následující podmínky:

  • Hlavička Accept-Encoding je přítomna s hodnotou br, , gzip*nebo vlastní kódování, které odpovídá vlastnímu poskytovateli komprese. Hodnota nesmí být nebo musí mít identity hodnotu kvality (qvalue, q) nastavenou na hodnotu 0 (nula).
  • Typ MIME (Content-Type) musí být nastaven a musí odpovídat typu MIME nakonfigurovaného v objektu ResponseCompressionOptions.
  • Požadavek nesmí obsahovat hlavičku Content-Range .
  • Požadavek musí používat nezabezpečený protokol (http), pokud není v možnostech middlewaru komprese odpovědi nakonfigurovaný zabezpečený protokol (https). Při povolování zabezpečené komprese obsahu si všimněte výše popsaného nebezpečí.

Ukázka nasazená v Azure

Ukázková aplikace nasazená do Azure obsahuje následující Program.cs soubor:

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

Další materiály

Poznámka:

Odkazy na dokumentaci k referenčnímu zdroji .NET obvykle načítají výchozí větev úložiště, která představuje aktuální vývoj pro příští verzi .NET. Pokud chcete vybrat značku pro konkrétní verzi, použijte rozevírací seznam pro přepnutí větví nebo značek. Další informace najdete v tématu Jak vybrat značku verze zdrojového kódu ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Šířka pásma sítě je omezený prostředek. Zmenšení velikosti odpovědi obvykle zvyšuje rychlost odezvy aplikace, často výrazně. Jedním ze způsobů, jak snížit velikost datové části, je komprimovat odpovědi aplikace.

Zobrazení nebo stažení ukázkového kódu (postup stažení)

Kdy použít middleware pro kompresi odpovědí

Používejte technologie komprese odpovědí založené na serveru ve službě IIS, Apache nebo Nginx. Výkon middlewaru pravděpodobně nebude odpovídat výkonu modulů serveru. HTTP.sys server a Kestrel server v současné době nenabízí integrovanou podporu komprese.

Middleware pro kompresi odpovědí použijte, když jste:

Komprese odpovědí

Každá odpověď, která není nativně komprimovaná, může obvykle těžit z komprese odpovědí. Mezi odpovědi, které nejsou nativně komprimované, obvykle patří: CSS, JavaScript, HTML, XML a JSON. Nativně komprimované prostředky, například soubory PNG, byste neměli komprimovat. Pokud se pokusíte dále komprimovat nativně komprimovanou odpověď, jakékoli malé další zmenšení velikosti a doby přenosu budou pravděpodobně zastíněny časem, který trvalo zpracování komprese. Nekomprimujte soubory menší než asi 150–1000 bajtů (v závislosti na obsahu souboru a efektivitě komprese). Režie komprimace malých souborů může způsobit komprimovaný soubor větší než nekomprimovaný soubor.

Když klient může zpracovávat komprimovaný obsah, musí klient informovat server o jeho schopnostech odesláním Accept-Encoding hlavičky s požadavkem. Když server odesílá komprimovaný obsah, musí obsahovat informace v Content-Encoding hlavičce o tom, jak je komprimovaná odpověď kódována. V následující tabulce jsou uvedena označení kódování obsahu podporovaná middlewarem.

Accept-Encoding hodnoty záhlaví Podporovaný middleware Popis
br Ano (výchozí) Komprimovaný formát dat Brotli
deflate No DEFLATE komprimovaný formát dat
exi No W3C Efektivní výměna XML
gzip Ano Formát souboru Gzip
identity Ano Identifikátor Bez kódování: Odpověď nesmí být zakódována.
pack200-gzip No Formát přenosu sítě pro archivy Java
* Ano Jakékoli kódování dostupného obsahu, které není explicitně požadováno

Další informace najdete v oficiálním seznamu kódování obsahu IANA.

Middleware umožňuje přidat další zprostředkovatele komprese pro vlastní Accept-Encoding hodnoty hlaviček. Další informace najdete v části Vlastní zprostředkovatelé níže.

Middleware dokáže reagovat na kvalitu hodnoty (qvalue, q) váhy při odeslání klientem, aby upřednostňoval schémata komprese. Další informace naleznete v dokumentu RFC 9110: Accept-Encoding.

Algoritmy komprese podléhají kompromisu mezi rychlostí komprese a účinností komprese. Účinnost v tomto kontextu odkazuje na velikost výstupu po kompresi. Nejmenší velikost se dosahuje nejoptimálnější kompresí.

Hlavičky, které se týkají vyžádání, odesílání, ukládání do mezipaměti a příjmu komprimovaného obsahu, jsou popsány v následující tabulce.

Hlavička Role
Accept-Encoding Odesláno z klienta na server, aby indikuje schémata kódování obsahu přijatelná pro klienta.
Content-Encoding Odesláno ze serveru klientovi, které označuje kódování obsahu v datové části.
Content-Length Když dojde k kompresi, Content-Length záhlaví se odebere, protože obsah těla se změní při komprimaci odpovědi.
Content-MD5 Když dojde ke kompresi, Content-MD5 záhlaví se odebere, protože se změnil základní obsah a hodnota hash už není platná.
Content-Type Určuje typ MIME obsahu. Každá odpověď by měla být zadána .Content-Type Middleware zkontroluje tuto hodnotu a určí, jestli má být odpověď komprimována. Middleware určuje sadu výchozích typů MIME, které může kódovat, ale můžete nahradit nebo přidat typy MIME.
Vary Když server odešle hodnotu Accept-Encoding klientům a proxy serverům, Vary hlavička značí klientovi nebo proxy serveru, že by se měly ukládat odpovědi (různé) v závislosti na hodnotě Accept-Encoding hlavičky požadavku. Výsledkem vrácení obsahu s hlavičkou Vary: Accept-Encoding je, že komprimované i nekomprimované odpovědi se ukládají do mezipaměti samostatně.

Prozkoumejte funkce middlewaru pro kompresi odpovědí pomocí ukázkové aplikace. Ukázka ukazuje:

  • Komprese odpovědí aplikace pomocí Gzip a vlastních poskytovatelů komprese.
  • Jak přidat typ MIME do výchozího seznamu typů MIME pro kompresi.

Konfigurace

Následující kód ukazuje, jak povolit middleware Komprese odpovědí pro výchozí typy MIME a zprostředkovatele komprese (Brotli a Gzip):

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

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

Poznámky:

  • app.UseResponseCompression musí být volána před jakýmkoli middlewarem, který komprimuje odpovědi. Další informace najdete v tématu Middleware ASP.NET Core.
  • Pomocí nástroje, jako je Fiddler, Firefox Browser Developer , nastavte hlavičku Accept-Encoding požadavku a prostudujte si hlavičky, velikost a text odpovědi.

Odešlete požadavek do ukázkové aplikace bez hlavičky Accept-Encoding a všimněte si, že odpověď není dekomprimovaná. V Content-Encoding odpovědi nejsou k dispozici hlavičky a Vary hlavičky.

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

Odešlete požadavek do ukázkové aplikace pomocí Accept-Encoding: br hlavičky (komprese Brotli) a všimněte si, že je odpověď komprimovaná. Vary V Content-Encoding odpovědi jsou k dispozici hlavičky.

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.

Poskytovatelé

Brotli Compression Provider

BrotliCompressionProvider Slouží ke komprimaci odpovědí pomocí komprimovaného datového formátu Brotli.

Pokud nejsou do CompressionProviderCollection: explicitně přidáni žádní poskytovatelé komprese:

  • Poskytovatel komprese Brotli je ve výchozím nastavení přidán do pole zprostředkovatelů komprese spolu s zprostředkovateli komprese Gzip.
  • Komprese je ve výchozím nastavení brotli komprese, pokud klient podporuje komprimovaný datový formát Brotli. Pokud klient brotli nepodporuje, komprese se ve výchozím nastavení nastaví na Gzip, pokud klient podporuje kompresi Gzip.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

Zprostředkovatel komprese Brotli musí být přidán při explicitně přidaném poskytovateli komprese:

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

Nastavte úroveň komprese pomocí BrotliCompressionProviderOptions. Poskytovatel komprese Brotli ve výchozím nastavení nastaví nejrychlejší úroveň komprese (CompressionLevel.Fastest), která nemusí způsobit nejúčinnější kompresi. Pokud je požadovaná nejúčinnější komprese, nakonfigurujte middleware pro optimální kompresi.

Úroveň komprese Popis
CompressionLevel.Fastest Komprese by se měla co nejrychleji dokončit, i když výsledný výstup není optimálně komprimovaný.
CompressionLevel.NoCompression Neměla by se provádět žádná komprese.
CompressionLevel.Optimal Odpovědi by měly být optimálně komprimovány, i když komprese trvá déle, než se dokončí.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

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

Zprostředkovatel komprese Gzip

GzipCompressionProvider K kompresi odpovědí použijte formát souboru Gzip.

Pokud nejsou do CompressionProviderCollection: explicitně přidáni žádní poskytovatelé komprese:

  • Zprostředkovatel komprese Gzip je ve výchozím nastavení přidán do pole zprostředkovatelů komprese spolu s Brotli Compression Provider.
  • Komprese je ve výchozím nastavení brotli komprese, pokud klient podporuje komprimovaný datový formát Brotli. Pokud klient brotli nepodporuje, komprese se ve výchozím nastavení nastaví na Gzip, pokud klient podporuje kompresi Gzip.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

Zprostředkovatel komprese Gzip musí být přidán, pokud jsou explicitně přidáni zprostředkovatelé komprese:

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

Nastavte úroveň komprese pomocí GzipCompressionProviderOptions. Zprostředkovatel komprese Gzip ve výchozím nastavení nastaví nejrychlejší úroveň komprese (CompressionLevel.Fastest), která nemusí způsobit nejúčinnější kompresi. Pokud je požadovaná nejúčinnější komprese, nakonfigurujte middleware pro optimální kompresi.

Úroveň komprese Popis
CompressionLevel.Fastest Komprese by se měla co nejrychleji dokončit, i když výsledný výstup není optimálně komprimovaný.
CompressionLevel.NoCompression Neměla by se provádět žádná komprese.
CompressionLevel.Optimal Odpovědi by měly být optimálně komprimovány, i když komprese trvá déle, než se dokončí.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

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

Vlastní poskytovatelé

Vytváření vlastních implementací komprese pomocí ICompressionProvider. Představuje EncodingName kódování obsahu, které se tím ICompressionProvider vytvoří. Middleware používá tyto informace k výběru poskytovatele na základě seznamu zadaného Accept-Encoding v hlavičce požadavku.

Pomocí ukázkové aplikace klient odešle požadavek s hlavičkou Accept-Encoding: mycustomcompression . Middleware používá vlastní implementaci komprese a vrátí odpověď s hlavičkou Content-Encoding: mycustomcompression . Aby vlastní implementace komprese fungovala, musí být klient schopen dekomprimovat vlastní kódová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" });
    });
}
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;
    }
}

Odešlete požadavek do ukázkové aplikace s hlavičkou Accept-Encoding: mycustomcompression a sledujte hlavičky odpovědi. Content-Encoding V Vary odpovědi jsou k dispozici hlavičky. Text odpovědi (není zobrazený) není zkomprimován ukázkou. Ve třídě ukázky není implementace CustomCompressionProvider komprese. Ukázka ale ukazuje, kde byste takový algoritmus komprese implementovali.

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.

typy MIME

Middleware určuje výchozí sadu typů MIME pro kompresi:

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

Nahraďte nebo připojte typy MIME možnostmi middlewaru Komprese odpovědí. Všimněte si, že typy MIME se zástupnými znaménkami, například text/* se nepodporují. Ukázková aplikace přidá typ MIME pro image/svg+xml a komprimuje a obsluhuje obrázek banneru 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" });
    });
}

Komprese pomocí zabezpečeného protokolu

Komprimované odpovědi přes zabezpečená připojení je možné ovládat pomocí EnableForHttps možnosti, která je ve výchozím nastavení zakázaná. Použití komprese s dynamicky generovanými stránkami může vést k problémům se zabezpečením, jako jsou útoky CRIME a BREACH útoky.

Přidání záhlaví Vary

Při komprimaci odpovědí na Accept-Encoding základě hlavičky existuje potenciálně více komprimovaných verzí odpovědi a nekomprimované verze. Aby bylo možné dát klientovi a proxy mezipaměti pokyn, aby existovalo více verzí a mělo by se uložit, Vary přidá se hlavička s Accept-Encoding hodnotou. V ASP.NET Core 2.0 nebo novějším middleware přidá hlavičku Vary automaticky při komprimaci odpovědi.

Problém s middlewarem za reverzním proxy serverem Nginx

Když Nginx proxiuje požadavek, hlavička Accept-Encoding se odebere. Odebrání hlavičky Accept-Encoding brání middlewaru v komprimaci odpovědi. Další informace naleznete v tématu NGINX: Komprese a dekomprese. Tento problém sleduje předávací komprese Nginx (dotnet/aspnetcore#5989).

Práce s dynamickou kompresí služby IIS

Pokud máte aktivní modul dynamické komprese služby IIS nakonfigurovaný na úrovni serveru, který chcete pro aplikaci zakázat, zakažte modul s přidáním souboru web.config . Další informace naleznete v tématu Zakázání modulů služby IIS.

Řešení problému

Použijte nástroj, jako je Fiddler nebo Firefox Browser Developer, který umožňuje nastavit hlavičku Accept-Encoding požadavku a studovat hlavičky, velikost a text odpovědi. Middleware komprese odpovědí ve výchozím nastavení komprimuje odpovědi, které splňují následující podmínky:

  • Hlavička Accept-Encoding se nachází s hodnotou br, , gzip*, nebo vlastní kódování, které odpovídá vlastní zprostředkovatel komprese, který jste vytvořili. Hodnota nesmí být nebo musí mít identity hodnotu kvality (qvalue, q) nastavenou na hodnotu 0 (nula).
  • Typ MIME (Content-Type) musí být nastaven a musí odpovídat typu MIME nakonfigurovaného v objektu ResponseCompressionOptions.
  • Požadavek nesmí obsahovat hlavičku Content-Range .
  • Požadavek musí používat nezabezpečený protokol (http), pokud není v možnostech middlewaru komprese odpovědi nakonfigurovaný zabezpečený protokol (https). Při povolování zabezpečené komprese obsahu si všimněte výše popsaného nebezpečí.

Další materiály