Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Šíř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 zmenšit velikost datové části, je komprimovat odpovědi z aplikace. Tento článek popisuje, jak implementovat kompresi odpovědí pro vaše aplikace pomocí middlewaru Komprese odpovědí v ASP.NET Core.
Prozkoumání 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 u dynamicky generovaných stránek může aplikaci vystavit CRIME a BREACH útokům. CRIME a BREACH útoky je možné zmírnit v ASP.NET Core pomocí antiforgery tokenů. 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 http://www.breachattack.com/.
I když aplikace zakáže vlastnost EnableForHttps (false), Internetové Informační Služby (IIS), IIS Express a Azure App Service může použít Gzip na webovém serveru IIS. Při kontrole hlaviček odpovědí si poznamenejte hodnotu hlavičky serveru . Neočekávaná hodnota hlavičky odpovědi content-encoding může být výsledkem webového serveru, nikoli konfigurace ASP.NET Core aplikace.
Urč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 komprese odpovědí pravděpodobně nemůže odpovídat výkonu modulů serveru. Server HTTP.sys a Kestrel server v současné době nenabízejí 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:
Prozkoumejte kompresi 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é soubory, jako jsou například soubory PNG. Při pokusu o další komprimaci nativně komprimované odpovědi je pravděpodobné, že jakékoli malé zmenšení velikosti a času přenosu je pravděpodobně zastíněno časem potřebným ke zpracování komprese. Nekomprimujte soubory menší než asi 150 – 1 000 bajtů v závislosti na obsahu souboru a efektivitě komprese. Náklady na komprimaci malých souborů mohou způsobit, že komprimovaný soubor bude větší než nekomprimovaný.
Když klient může zpracovávat komprimovaný obsah, musí klient informovat server o jeho schopnostech odesláním hlavičky Accept-Encoding s požadavkem. Když server odesílá komprimovaný obsah, musí obsahovat informace v hlavičce Content-Encoding týkající se kódování komprimované odpovědi.
Následující tabulka uvádí označení kódování obsahu pro hlavičku Accept-Encoding a označuje, jestli middleware komprese odpovědí podporuje označení.
| Označení | Middleware | Formát | Podrobnosti |
|---|---|---|---|
br |
Ano (výchozí) | Formát komprimovaných dat Brotli | RFC 7932 |
deflate |
No | DEFLATE Komprimovaný formát dat | RFC 1951 |
exi |
No | Efektivní výměna XML (EXI) | Doporučení W3C |
gzip |
Yes | Formát souboru Gzip | RFC 1952 |
identity |
Yes | "Bez kódování" – odpověď nesmí být zakódovaná. | Řešení potíží s kompresí odpovědí |
pack200-gzip |
No | Formát přenosu sítě pro archivy Java | JSR 200 |
* (hvězdička) |
Yes | Zástupný znak – jakékoli dostupné kódování obsahu, které není explicitně požadováno | Řešení potíží s kompresí odpovědí |
Další informace najdete v oficiálním seznamu kódování obsahu IANA pro parametry HTTP.
Middleware komprese odpovědí umožňuje přidat další zprostředkovatele komprese pro vlastní Accept-Encoding hodnoty hlaviček. Další informace najdete v části Vlastní zprostředkovatelé dále v tomto článku.
Middleware komprese odpovědí je schopen reagovat na hodnotu kvality (qvalue, q) zohledněnou při odesílání klientem k upřednostnění schémat komprese. Další informace naleznete v dokumentu RFC 9110: Sémantika HTTP (oddíl 12.5.3 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ší velikosti je dosaženo pomocí 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.
| Header | Role | Podrobnosti |
|---|---|---|
Accept-Encoding |
Odesláno z klienta na server, aby indikuje schémata kódování obsahu přijatelná pro klienta. | záhlaví Accept-Encoding |
Content-Encoding |
Odesláno ze serveru klientovi, aby označil kódování obsahu v datové části. | Hlavička Content-Encoding |
Content-Length |
Když dojde k kompresi, Content-Length záhlaví se odebere, protože se obsah těla změní při kompresi odpovědi. |
Hlavička Content-Length |
Content-MD5 |
Když dojde ke kompresi, Content-MD5 se hlavička odebere, protože se změní obsah těla a hodnota hash už není platná. |
RFC 1864: Pole hlavičky Content-MD5 |
Content-Type |
Určuje typ MIME obsahu. Každá odpověď by měla zadat její Content-Type hodnotu. 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. |
Hlavička typu obsahu |
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ě. |
Různá záhlaví |
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 middlewaru komprese odpovědí
Následující kód ukazuje, jak povolit middleware pro kompresi odpovědí pro výchozí MIME typy a poskytovatele 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 k middlewaru pro kompresi odpovědí
Při práci s middlewarem Pro kompresi odpovědí mějte na paměti následující body:
- Nastavení
EnableForHttpsvlastnostitrueje bezpečnostní riziko. Další informace najdete v části Komprese s HTTPS výše v tomto článku. - Aplikace musí zavolat metodu app.UseResponseCompressionpřed jakýmkoli middlewarem, který komprimuje odpovědi. Další informace najdete v tématu ASP.NET Core Middleware > pořadí middlewaru.
- K nastavení hlavičky požadavku a prozkoumání hlaviček, velikosti a textu požadavku použijte nástroj, jako je
Accept-EncodingEdition.
Odešlete požadavek do ukázkové aplikace bez hlavičky Accept-Encoding a všimněte si, že odpověď není dekomprimovaná. Záhlaví Content-Encoding není v kolekci odpovědi Headers.
Například ve Firefoxu Developer:
- Vyberte kartu sítě.
- Klikněte pravým tlačítkem myši na požadavek v seznamu síťových požadavků a vyberte Upravit a znovu odeslat.
-
Accept-Encoding:Změňte hodnotu zgzip, deflate, brnanone. - Vyberte Odeslat.
Odešlete žádost do ukázkové aplikace v prohlížeči pomocí vývojářských nástrojů a všimněte si, že odpověď je komprimovaná. Na odpovědi jsou přítomny hlavičky Content-Encoding a Vary.
Posouzení poskytovatelů
Tato část obsahuje podrobnosti o poskytovatelích komprese, včetně Brotli, Gzip a vlastních poskytovatelů.
Poskytovatelé komprese Brotli a Gzip
Třídu BrotliCompressionProvider použijte ke komprimaci odpovědí pomocí RFC 7932: Brotli Compressed Data Format.
Pokud do třídy nejsou explicitně přidáni žádní zprostředkovatelé komprese:CompressionProviderCollection
- Ve výchozím nastavení jsou zprostředkovatelé komprese Brotli a Gzip přidány do pole zprostředkovatelů komprese.
- Když klient podporuje formát komprimovaných dat Brotli, ve výchozím nastavení se použije komprese Brotli.
- Pokud klient nepodporuje Brotli, komprese se ve výchozím nastavení nastaví na Gzip, pokud klient podporuje kompresi Gzip.
Když přidáte poskytovatele komprese, ostatní poskytovatelé 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.
Note
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).
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 pomocí BrotliCompressionProviderOptions třídy a GzipCompressionProviderOptions třídy. Poskytovatelé komprese Brotli a Gzip mají ve výchozím nastavení nastavenu nejrychlejší úroveň komprese, jak je určeno ve výčtu CompressionLevel.Fastest. Tento přístup však nemusí způsobit nejúčinnější kompresi. Pokud je požadovaná nejúčinnější komprese, nakonfigurujte middleware komprese odpovědí pro optimální kompresi.
Hodnoty, které označují, zda operace komprese upřednostňuje rychlost nebo velikost, najdete ve výčtu CompressionLevel.
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é
Vytvořte vlastní implementace komprese pomocí ICompressionProvider rozhraní. Vlastnost EncodingName představuje kódování obsahu, které to 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;
}
}
V předchozím kódu příklad nekomprimuje tělo odpovědi. Ukázka ale ukazuje, kde implementovat vlastní algoritmus komprese.
Kontrola typů 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.
Note
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řepínání 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 pomocí vlastnosti ResponseCompressionOptions.MimeTypes. Typy MIME se zástupnými znaky, jako text/* jsou nepodporovaná. Ukázková aplikace přidá typ MIME pro image/svg+xml a komprimuje a poskytuje bannerový obrázek 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řidejte hlavičku Vary
Pokud jsou odpovědi komprimovány na základě hlavičky požadavku Accept-Encoding, může existovat jedna nekomprimovaná a více komprimovaných verzí odpovědi. Pokud je potřeba informovat klientské a proxy servery, že existuje více verzí a měly by být uloženy, přidá se hlavička Vary s hodnotou Accept-Encoding. Middleware odpovědi přidá hlavičku Vary do souboru ResponseCompressionBody.cs automaticky při komprimaci odpovědi.
Note
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 určité vydání, použijte rozbalovací 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émy s reverzním proxy serverem Nginx
Když Nginx proxy zpracovává požadavek, Accept-Encoding záhlaví je odstraněno. Odebrání hlavičky Accept-Encoding zabraňuje middlewaru pro kompresi odpovědí komprimovat odpověď. Další informace naleznete v tématu Nginx: Komprese a dekomprese. Tento problém se sleduje v problému na GitHubu dotnet/aspnetcore #5989 - Vyřešte průchozí kompresi pro Nginx.
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 – Edice 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-Encodingse nachází s hodnotoubr,gzip,*(hvězdička) nebo vlastní kódování odpovídající vlastnímu poskytovateli komprese. Hodnota nesmí býtidentity(bez kódování) nebo musí mít hodnotu kvality (qvalue,q) nastavenou na hodnotu 0 (nula).Musí být nastaven typ MIME (
Content-Type) a musí odpovídat typu MIME nakonfigurovaného ve ResponseCompressionOptions třídě.Požadavek nesmí obsahovat hlavičku Content-Range.
Požadavek musí používat nezabezpečený hypertextový protokol (http), pokud není v možnostech middlewaru komprese odpovědi nakonfigurovaný zabezpečený protokol hypertextu (https).
Important
Projděte si rizika spojená s povolením zabezpečené komprese obsahu, jak je popsáno v části Komprese s HTTPS výše v tomto článku.
Kontrola ukázky nasazené v Azure
Ukázková aplikace nasazená do Azure má následující soubor 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();
Související obsah
Šíř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 datových 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é soubory, 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). Náklady na kompresi malých souborů mohou způsobit, že komprimovaný soubor je větší než nekomprimovaný.
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 | Description |
|---|---|---|
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 |
Yes | Formát souboru Gzip |
identity |
Yes | 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 |
* |
Yes | 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 je schopné reagovat na vážení kvality hodnoty (qvalue, q), když je odesláno klientem, aby upřednostnilo 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 dosáhne optimální 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.
| Header | 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, aby označil kódování obsahu v datové části. |
Content-Length |
Při komprimaci se Content-Length záhlaví odebere, protože se změní obsah těla zprávy 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 specifikovat své 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.
Configuration
Následující kód ukazuje, jak povolit middleware pro Kompresi 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();
}
}
Notes:
-
app.UseResponseCompressionmusí 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 nebo Firefox Browser Developer, nastavte
Accept-Encodinghlavičku požadavku a prostudujte si hlavičky odpovědi, její velikost a tělo.
Odešlete požadavek do ukázkové aplikace bez hlavičky Accept-Encoding a všimněte si, že odpověď není dekomprimovaná. V odpovědi nejsou přítomny hlavičky Content-Encoding ani hlavičky Vary.
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á. Na odpovědi jsou přítomny hlavičky Content-Encoding a Vary.
Providers
Poskytovatel komprese Brotli
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.
- Ve výchozím nastavení se používá komprese Brotli, 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, když jsou explicitně přidáni nějací 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í 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 | Description |
|---|---|
| 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.
- Ve výchozím nastavení se používá komprese Brotli, 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 | Description |
|---|---|
| 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.
EncodingName představuje kódování obsahu, které ICompressionProvider vytváří. 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. Na odpovědi jsou přítomny hlavičky Vary a Content-Encoding. Text odpovědi (není zobrazen) není vzorkem zkomprimován. Ve třídě CustomCompressionProvider ukázky není implementována komprese. Ukázka ale ukazuje, kde byste takový algoritmus komprese implementovali.
Typy MIME
Middleware určuje výchozí sadu typů MIME pro kompresi:
application/javascriptapplication/jsonapplication/xmltext/csstext/htmltext/jsontext/plaintext/xml
Nahraďte nebo připojte typy MIME možnostmi middlewaru pro kompresi 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.
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é informovat klientské a proxy mezipaměti, že existuje více verzí, které by měly být uloženy, je přidána hlavička Vary s hodnotou Accept-Encoding. 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.
Troubleshooting
Použijte nástroj, jako je Fiddler nebo Firefox Browser Developer, které vám umožní nastavit hlavičku žádosti Accept-Encoding a studovat hlavičky odpovědi, jejich velikost a tělo. Middleware komprese odpovědí ve výchozím nastavení komprimuje odpovědi, které splňují následující podmínky:
- Hlavička
Accept-Encodingse nachází s hodnotoubr,gzip,*nebo vlastní kódování, které odpovídá vlastnímu zprostředkovateli komprese, který jste vytvořili. Hodnota nesmí býtidentitynebo mít hodnotu kvality (qvalue,q) nastavenou na 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čí.