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
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:
- Nelze použít následující technologie komprese založené na serveru:
- Hostování přímo na:
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:
true
NastaveníEnableForHttps
je bezpečnostní riziko. Další informace najdete v části Komprese s HTTPS v tomto článku.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 prohlížeč Firefox Browser Developer , nastavte hlavičku
Accept-Encoding
požadavku a prozkoumejte 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á. 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:
zgzip, deflate, br
nanone
. - 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 hodnotoubr
, ,gzip
*
nebo vlastní kódování, které odpovídá vlastnímu poskytovateli komprese. Hodnota nesmí být nebo musí mítidentity
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:
- Nelze použít následující technologie komprese založené na serveru:
- Hostování přímo na:
- HTTP.sys server (dříve WebListener)
- Kestrel server
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.
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.
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.
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 hodnotoubr
, ,gzip
*
, nebo vlastní kódování, které odpovídá vlastní zprostředkovatel komprese, který jste vytvořili. Hodnota nesmí být nebo musí mítidentity
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čí.