Kompresja odpowiedzi w ASP.NET Core
Przepustowość sieci jest ograniczonym zasobem. Zmniejszenie rozmiaru odpowiedzi zwykle zwiększa czas reakcji aplikacji, często dramatycznie. Jednym ze sposobów zmniejszenia rozmiarów ładunków jest kompresowanie odpowiedzi aplikacji.
Kompresja przy użyciu protokołu HTTPS
Skompresowane odpowiedzi za pośrednictwem bezpiecznych połączeń można kontrolować za pomocą opcji, która jest domyślnie wyłączona ze EnableForHttps względu na ryzyko bezpieczeństwa. Użycie kompresji z dynamicznie wygenerowanymi stronami może uwidocznić aplikację i CRIME BREACH ataki. CRIME ataki i BREACH ataki można ograniczyć w ASP.NET Core przy użyciu tokenów antyforgeryjnych. Aby uzyskać więcej informacji, zobacz Zapobieganie atakom z fałszowaniem żądań międzywitrynowych (XSRF/CSRF) na platformie ASP.NET Core. Aby uzyskać informacje na temat ograniczania BREACH ataków, zobacz środki zaradcze w witrynie http://www.breachattack.com/
Nawet w przypadku EnableForHttps
wyłączenia w aplikacji usługi IIS, IIS Express i aplikacja systemu Azure Service można zastosować gzip na serwerze internetowym usług IIS. Podczas przeglądania nagłówków odpowiedzi zanotuj wartość Serwer . content-encoding
Nieoczekiwana wartość nagłówka odpowiedzi może być wynikiem serwera internetowego, a nie konfiguracji aplikacji ASP.NET Core.
Kiedy należy używać oprogramowania pośredniczącego kompresji odpowiedzi
Używaj technologii kompresji odpowiedzi opartych na serwerze w usługach IIS, Apache lub Nginx. Wydajność oprogramowania pośredniczącego kompresji odpowiedzi prawdopodobnie nie będzie zgodna z wydajnością modułów serwera. HTTP.sys serwer i Kestrel serwer nie oferują obecnie wbudowanej obsługi kompresji.
Użyj oprogramowania pośredniczącego kompresji odpowiedzi, gdy aplikacja jest:
- Nie można użyć następujących technologii kompresji opartej na serwerze:
- Hosting bezpośrednio w:
Kompresja odpowiedzi
Zwykle każda odpowiedź nieskompresowana natywnie może korzystać z kompresji odpowiedzi. Odpowiedzi nie są kompresowane natywnie, zazwyczaj obejmują pliki CSS, JavaScript, HTML, XML i JSON. Nie kompresuj natywnie skompresowanych zasobów, takich jak pliki PNG. Podczas próby dalszego skompresowania natywnie skompresowanej odpowiedzi wszelkie niewielkie dodatkowe zmniejszenie rozmiaru i czasu transmisji prawdopodobnie zostanie przyćmione przez czas potrzebny do przetworzenia kompresji. Nie kompresuj plików mniejszych niż około 150–1000 bajtów, w zależności od zawartości pliku i wydajności kompresji. Obciążenie związane z kompresowaniem małych plików może spowodować wygenerowanie skompresowanego pliku większego niż nieskompresowany plik.
Gdy klient może przetworzyć skompresowaną zawartość, klient musi poinformować serwer o jego możliwościach, wysyłając Accept-Encoding
nagłówek z żądaniem. Gdy serwer wysyła skompresowaną zawartość, musi zawierać informacje w nagłówku Content-Encoding
na temat kodowania skompresowanej odpowiedzi. Oznaczenia kodowania zawartości obsługiwane przez oprogramowanie pośredniczące kompresji odpowiedzi są wyświetlane w poniższej tabeli.
Accept-Encoding wartości nagłówka |
Obsługiwane oprogramowanie pośredniczące | opis |
---|---|---|
br |
Tak (ustawienie domyślne) | Format skompresowanych danych Brotli |
deflate |
Nie. | Format skompresowanych danych DEFLATE |
exi |
Nie. | Wydajna wymiana XML W3C |
gzip |
Tak | Format pliku Gzip |
identity |
Tak | Identyfikator "Brak kodowania": Odpowiedź nie może być zakodowana. |
pack200-gzip |
Nie. | Format transferu sieciowego dla archiwów Java |
* |
Tak | Wszelkie dostępne kodowanie zawartości, których nie zażądano jawnie |
Aby uzyskać więcej informacji, zobacz oficjalną listę kodowania zawartości IANA.
Oprogramowanie pośredniczące kompresji odpowiedzi umożliwia dodawanie dodatkowych dostawców kompresji dla niestandardowych Accept-Encoding
wartości nagłówka. Aby uzyskać więcej informacji, zobacz Dostawcy niestandardowi w tym artykule.
Oprogramowanie pośredniczące kompresji odpowiedzi może reagować na wartość jakości (qvalue, q
) wagi wysyłane przez klienta w celu nadania priorytetów schematom kompresji. Aby uzyskać więcej informacji, zobacz RFC 9110: Accept-Encoding (RFC 9110: Kodowanie akceptowania).
Algorytmy kompresji podlegają kompromisowi między szybkością kompresji a skutecznością kompresji. Skuteczność w tym kontekście odnosi się do rozmiaru danych wyjściowych po kompresji. Najmniejszy rozmiar jest osiągany przez optymalną kompresję.
Nagłówki związane z żądaniem, wysyłaniem, buforowaniem i odbieraniem skompresowanej zawartości są opisane w poniższej tabeli.
Nagłówek | Rola |
---|---|
Accept-Encoding |
Wysłane z klienta do serwera w celu wskazania schematów kodowania zawartości akceptowalnych dla klienta. |
Content-Encoding |
Wysłane z serwera do klienta, aby wskazać kodowanie zawartości w ładunku. |
Content-Length |
W przypadku kompresji nagłówek jest usuwany, Content-Length ponieważ zawartość treści zmienia się po skompresowaniu odpowiedzi. |
Content-MD5 |
Gdy występuje kompresja Content-MD5 , nagłówek zostanie usunięty, ponieważ zawartość treści uległa zmianie, a skrót nie jest już prawidłowy. |
Content-Type |
Określa typ MIME zawartości. Każda odpowiedź powinna określać jego Content-Type wartość . Oprogramowanie pośredniczące kompresji odpowiedzi sprawdza tę wartość, aby określić, czy odpowiedź powinna zostać skompresowana. Oprogramowanie pośredniczące kompresji odpowiedzi określa zestaw domyślnych typów MIME, które może zakodować, i mogą zostać zastąpione lub dodane. |
Vary |
Po wysłaniu przez serwer z wartością Accept-Encoding do klientów i serwerów proxy Vary nagłówek wskazuje klientowi lub serwerowi proxy, że powinna buforować (różne) odpowiedzi na podstawie wartości Accept-Encoding nagłówka żądania. Wynikiem zwracania zawartości z nagłówkiem Vary: Accept-Encoding jest to, że zarówno skompresowane, jak i nieskompresowane odpowiedzi są buforowane oddzielnie. |
Zapoznaj się z funkcjami oprogramowania pośredniczącego kompresji odpowiedzi za pomocą przykładowej aplikacji. Przykład ilustruje:
- Kompresja odpowiedzi aplikacji przy użyciu Gzip i niestandardowych dostawców kompresji.
- Jak dodać typ MIME do domyślnej listy typów MIME na potrzeby kompresji.
- Jak dodać niestandardowego dostawcę kompresji odpowiedzi.
Konfigurowanie
Poniższy kod pokazuje, jak włączyć oprogramowanie pośredniczące kompresji odpowiedzi dla domyślnych typów MIME i dostawców kompresji (Brotli i 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();
Uwagi:
- Ustawienie
EnableForHttps
wartości totrue
zagrożenie bezpieczeństwa. Aby uzyskać więcej informacji, zobacz Kompresja przy użyciu protokołu HTTPS w tym artykule. app.UseResponseCompression
należy wywołać przed każdym oprogramowaniem pośredniczącym, które kompresuje odpowiedzi. Aby uzyskać więcej informacji, zobacz Oprogramowanie pośredniczące ASP.NET Core.- Użyj narzędzia, takiego jak Firefox Browser Developer , aby ustawić
Accept-Encoding
nagłówek żądania i zbadać nagłówki odpowiedzi, rozmiar i treść.
Prześlij żądanie do przykładowej aplikacji bez nagłówka Accept-Encoding
i sprawdź, czy odpowiedź jest nieskompresowana. Nagłówek Content-Encoding
nie znajduje się w kolekcji Nagłówki odpowiedzi.
Na przykład w przeglądarce Firefox Developer:
- Wybierz kartę sieć.
- Kliknij prawym przyciskiem myszy żądanie na liście Żądanie sieciowe, a następnie wybierz pozycję Edytuj i wyślij ponownie
- Zmień wartość
Accept-Encoding:
zgzip, deflate, br
nanone
. - Wybierz Wyślij.
Prześlij żądanie do przykładowej aplikacji za pomocą przeglądarki przy użyciu narzędzi deweloperskich i sprawdź, czy odpowiedź jest skompresowana. Nagłówki Content-Encoding
i Vary
znajdują się w odpowiedzi.
Dostawcy usługi
Dostawcy kompresji Brotli i Gzip
Użyj polecenia , BrotliCompressionProvider aby skompresować odpowiedzi za pomocą skompresowanego formatu danych Brotli.
Jeśli żaden dostawca kompresji nie zostanie jawnie dodany do elementu CompressionProviderCollection:
- Dostawca kompresji Brotli i dostawca kompresji Gzip są domyślnie dodawane do tablicy dostawców kompresji.
- Kompresja jest domyślnie kompresja Brotli, gdy skompresowany format danych Brotli jest obsługiwany przez klienta. Jeśli program Brotli nie jest obsługiwany przez klienta, kompresja jest domyślnie ustawiona na Gzip, gdy klient obsługuje kompresję Gzip.
Uwaga
Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Po dodaniu dostawcy kompresji inni dostawcy nie są dodawani. Jeśli na przykład dostawca kompresji Gzip jest jedynym dostawcą jawnie dodanym, żaden inny dostawca kompresji nie zostanie dodany.
Następujący kod powoduje:
- Włącza kompresję odpowiedzi dla żądań HTTPS.
- Dodaje dostawców kompresji odpowiedzi Brotli i 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();
Ustaw poziom kompresji na BrotliCompressionProviderOptions i GzipCompressionProviderOptions. Dostawcy kompresji Brotli i Gzip domyślnie do najszybszego poziomu kompresji CompressionLevel.Fastest, który może nie produkować najbardziej wydajnej kompresji. Jeśli jest wymagana najbardziej wydajna kompresja, skonfiguruj oprogramowanie pośredniczące kompresji odpowiedzi pod kątem optymalnej kompresji.
Zobacz CompressionLevel Enum ,aby uzyskać wartości wskazujące, czy operacja kompresji podkreśla szybkość, czy rozmiar kompresji.
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();
Dostawcy niestandardowi
Utwórz niestandardowe implementacje kompresji za pomocą polecenia ICompressionProvider. Obiekt EncodingName reprezentuje kodowanie zawartości, które powoduje wygenerowanie ICompressionProvider
. Oprogramowanie pośredniczące kompresji odpowiedzi używa tych informacji do wybrania dostawcy na podstawie listy określonej w Accept-Encoding
nagłówku żądania.
Żądania do przykładowej aplikacji z Accept-Encoding: mycustomcompression
nagłówkiem zwracają odpowiedź z nagłówkiem Content-Encoding: mycustomcompression
. Aby implementacja kompresji niestandardowej działała, klient musi mieć możliwość dekompresowania niestandardowego kodowania.
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;
}
}
W poprzednim kodzie treść odpowiedzi nie jest kompresowana przez przykład. Jednak w przykładzie pokazano, gdzie zaimplementować niestandardowy algorytm kompresji.
MIME, typy
Oprogramowanie pośredniczące kompresji odpowiedzi określa domyślny zestaw typów MIME na potrzeby kompresji. Zobacz kod źródłowy, aby uzyskać pełną listę obsługiwanych typów MIME.
Uwaga
Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Zastąp lub dołącz typy MIME .ResponseCompressionOptions.MimeTypes
Należy pamiętać, że typy MIME z symbolami wieloznacznymi, takie jak text/*
nie są obsługiwane. Przykładowa aplikacja dodaje typ MIME dla image/svg+xml
i kompresuje i obsługuje obraz baneru 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();
Dodawanie nagłówka Vary
Podczas kompresowania odpowiedzi na podstawie nagłówka Accept-Encoding
żądania mogą być nieskompresowane i wiele skompresowanych wersji odpowiedzi. Aby poinstruować pamięć podręczną klienta i serwera proxy, że istnieje wiele wersji i powinny być przechowywane, Vary
nagłówek jest dodawany z wartością Accept-Encoding
. Oprogramowanie pośredniczące odpowiedzi automatycznie dodaje Vary
nagłówek po skompresowaniu odpowiedzi.
Uwaga
Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Problem z oprogramowaniem pośredniczącym w przypadku wystąpienia zwrotnego serwera proxy Nginx
Gdy żądanie jest proxied przez serwer Nginx, Accept-Encoding
nagłówek zostanie usunięty. Usunięcie nagłówka Accept-Encoding
uniemożliwia kompresowanie odpowiedzi oprogramowania pośredniczącego kompresji odpowiedzi. Aby uzyskać więcej informacji, zobacz NGINX: kompresja i dekompresja. Ten problem jest śledzony przez rysunek kompresji przekazywania dla serwera Nginx (dotnet/aspnetcore#5989).
Wyłączanie kompresji dynamicznej usług IIS
Aby wyłączyć moduł kompresji dynamicznej usług IIS skonfigurowany na poziomie serwera, zobacz Wyłączanie modułów usług IIS.
Rozwiązywanie problemów z kompresją odpowiedzi
Użyj narzędzia, takiego jak Firefox Browser Developer, które umożliwia ustawianie nagłówka Accept-Encoding
żądania i badanie nagłówków odpowiedzi, rozmiaru i treści. Domyślnie oprogramowanie pośredniczące kompresji odpowiedzi kompresuje odpowiedzi spełniające następujące warunki:
- Nagłówek
Accept-Encoding
jest obecny z wartościąbr
,gzip
,*
lub niestandardowym kodowaniem zgodnym z niestandardowym dostawcą kompresji. Wartość nie może byćidentity
wartością jakości (qvalue,q
) ustawieniem 0 (zero). - Typ MIME (
Content-Type
) musi być ustawiony i musi być zgodny z typem MIME skonfigurowanym w obiekcie ResponseCompressionOptions. - Żądanie nie może zawierać nagłówka
Content-Range
. - Żądanie musi używać niezabezpieczonego protokołu (http), chyba że w opcjach oprogramowania pośredniczącego kompresji odpowiedzi skonfigurowano bezpieczny protokół (https). Zwróć uwagę na niebezpieczeństwo opisane powyżej podczas włączania bezpiecznej kompresji zawartości.
Przykład wdrożony na platformie Azure
Przykładowa aplikacja wdrożona na platformie Azure ma następujący Program.cs
plik:
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();
Dodatkowe zasoby
Uwaga
Linki dokumentacji do źródła referencyjnego platformy .NET zwykle ładują domyślną gałąź repozytorium, która odzwierciedla bieżące programowanie dla następnej wersji platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi. Aby uzyskać więcej informacji, zobacz Jak wybrać tag wersji kodu źródłowego platformy ASP.NET Core (dotnet/AspNetCore.Docs #26205).
- Wyświetl lub pobierz przykładowy kod (jak pobrać)
- Źródło oprogramowania pośredniczącego kompresji odpowiedzi
- oprogramowanie pośredniczące ASP.NET Core
- Mozilla Developer Network: Accept-Encoding
- RFC 9110 Sekcja 8.4.1: Kodowanie zawartości
- RFC 9110 Sekcja 8.4.1.3: Kodowanie Gzip
- Specyfikacja formatu pliku GZIP w wersji 4.3
Przepustowość sieci jest ograniczonym zasobem. Zmniejszenie rozmiaru odpowiedzi zwykle zwiększa czas reakcji aplikacji, często dramatycznie. Jednym ze sposobów zmniejszenia rozmiarów ładunków jest kompresowanie odpowiedzi aplikacji.
Wyświetl lub pobierz przykładowy kod (jak pobrać)
Kiedy należy używać oprogramowania pośredniczącego kompresji odpowiedzi
Używaj technologii kompresji odpowiedzi opartych na serwerze w usługach IIS, Apache lub Nginx. Wydajność oprogramowania pośredniczącego prawdopodobnie nie będzie zgodna z wydajnością modułów serwera. HTTP.sys serwer i Kestrel serwer nie oferują obecnie wbudowanej obsługi kompresji.
Użyj oprogramowania pośredniczącego kompresji odpowiedzi, gdy:
- Nie można użyć następujących technologii kompresji opartej na serwerze:
- Hosting bezpośrednio w:
- serwer HTTP.sys (dawniej WebListener)
- Kestrel serwer
Kompresja odpowiedzi
Zwykle każda odpowiedź nieskompresowana natywnie może korzystać z kompresji odpowiedzi. Odpowiedzi nie są zwykle kompresowane natywnie: CSS, JavaScript, HTML, XML i JSON. Nie należy kompresować natywnie skompresowanych zasobów, takich jak pliki PNG. Jeśli spróbujesz dodatkowo skompresować natywnie skompresowaną odpowiedź, wszelkie niewielkie dodatkowe zmniejszenie rozmiaru i czasu transmisji prawdopodobnie zostanie przyćmione przez czas potrzebny do przetworzenia kompresji. Nie kompresuj plików mniejszych niż około 150–1000 bajtów (w zależności od zawartości pliku i wydajności kompresji). Obciążenie związane z kompresowaniem małych plików może spowodować wygenerowanie skompresowanego pliku większego niż nieskompresowany plik.
Gdy klient może przetworzyć skompresowaną zawartość, klient musi poinformować serwer o jego możliwościach, wysyłając Accept-Encoding
nagłówek z żądaniem. Gdy serwer wysyła skompresowaną zawartość, musi zawierać informacje w nagłówku Content-Encoding
na temat kodowania skompresowanej odpowiedzi. Oznaczenia kodowania zawartości obsługiwane przez oprogramowanie pośredniczące są wyświetlane w poniższej tabeli.
Accept-Encoding wartości nagłówka |
Obsługiwane oprogramowanie pośredniczące | opis |
---|---|---|
br |
Tak (ustawienie domyślne) | Format skompresowanych danych Brotli |
deflate |
Nie. | Format skompresowanych danych DEFLATE |
exi |
Nie. | Wydajna wymiana XML W3C |
gzip |
Tak | Format pliku Gzip |
identity |
Tak | Identyfikator "Brak kodowania": Odpowiedź nie może być zakodowana. |
pack200-gzip |
Nie. | Format transferu sieciowego dla archiwów Java |
* |
Tak | Wszelkie dostępne kodowanie zawartości, których nie zażądano jawnie |
Aby uzyskać więcej informacji, zobacz oficjalną listę kodowania zawartości IANA.
Oprogramowanie pośredniczące umożliwia dodawanie dodatkowych dostawców kompresji dla niestandardowych Accept-Encoding
wartości nagłówka. Aby uzyskać więcej informacji, zobacz dostawcy niestandardowi poniżej.
Oprogramowanie pośredniczące może reagować na wartość jakości (qvalue, q
) w przypadku wysyłania przez klienta do określania priorytetów schematów kompresji. Aby uzyskać więcej informacji, zobacz RFC 9110: Accept-Encoding (RFC 9110: Kodowanie akceptowania).
Algorytmy kompresji podlegają kompromisowi między szybkością kompresji a skutecznością kompresji. Skuteczność w tym kontekście odnosi się do rozmiaru danych wyjściowych po kompresji. Najmniejszy rozmiar jest osiągany przez najbardziej optymalną kompresję.
Nagłówki związane z żądaniem, wysyłaniem, buforowaniem i odbieraniem skompresowanej zawartości są opisane w poniższej tabeli.
Nagłówek | Rola |
---|---|
Accept-Encoding |
Wysłane z klienta do serwera w celu wskazania schematów kodowania zawartości akceptowalnych dla klienta. |
Content-Encoding |
Wysłane z serwera do klienta, aby wskazać kodowanie zawartości w ładunku. |
Content-Length |
W przypadku kompresji nagłówek jest usuwany, Content-Length ponieważ zawartość treści zmienia się po skompresowaniu odpowiedzi. |
Content-MD5 |
Gdy występuje kompresja Content-MD5 , nagłówek zostanie usunięty, ponieważ zawartość treści uległa zmianie, a skrót nie jest już prawidłowy. |
Content-Type |
Określa typ MIME zawartości. Każda odpowiedź powinna określać jego Content-Type wartość . Oprogramowanie pośredniczące sprawdza tę wartość, aby określić, czy odpowiedź powinna zostać skompresowana. Oprogramowanie pośredniczące określa zestaw domyślnych typów MIME, które może kodować, ale można zastąpić lub dodać typy MIME. |
Vary |
Po wysłaniu przez serwer z wartością Accept-Encoding do klientów i serwerów proxy Vary nagłówek wskazuje klientowi lub serwerowi proxy, że powinna buforować (różne) odpowiedzi na podstawie wartości Accept-Encoding nagłówka żądania. Wynikiem zwracania zawartości z nagłówkiem Vary: Accept-Encoding jest to, że zarówno skompresowane, jak i nieskompresowane odpowiedzi są buforowane oddzielnie. |
Zapoznaj się z funkcjami oprogramowania pośredniczącego kompresji odpowiedzi za pomocą przykładowej aplikacji. Przykład ilustruje:
- Kompresja odpowiedzi aplikacji przy użyciu Gzip i niestandardowych dostawców kompresji.
- Jak dodać typ MIME do domyślnej listy typów MIME na potrzeby kompresji.
Konfigurowanie
Poniższy kod pokazuje, jak włączyć oprogramowanie pośredniczące kompresji odpowiedzi dla domyślnych typów MIME i dostawców kompresji (Brotli i Gzip):
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCompression();
}
}
Uwagi:
app.UseResponseCompression
należy wywołać przed każdym oprogramowaniem pośredniczącym, które kompresuje odpowiedzi. Aby uzyskać więcej informacji, zobacz Oprogramowanie pośredniczące ASP.NET Core.- Użyj narzędzia, takiego jak Fiddler, Firefox Browser Developer, aby ustawić
Accept-Encoding
nagłówek żądania i zbadać nagłówki odpowiedzi, rozmiar i treść.
Prześlij żądanie do przykładowej aplikacji bez nagłówka Accept-Encoding
i sprawdź, czy odpowiedź jest nieskompresowana. Nagłówki Content-Encoding
i Vary
nie są obecne w odpowiedzi.
Prześlij żądanie do przykładowej aplikacji z nagłówkiem Accept-Encoding: br
(kompresja Brotli) i sprawdź, czy odpowiedź jest skompresowana. Nagłówki Content-Encoding
i Vary
znajdują się w odpowiedzi.
Dostawcy usługi
Dostawca kompresji Brotli
Użyj polecenia , BrotliCompressionProvider aby skompresować odpowiedzi za pomocą skompresowanego formatu danych Brotli.
Jeśli żaden dostawca kompresji nie zostanie jawnie dodany do elementu CompressionProviderCollection:
- Dostawca kompresji Brotli jest domyślnie dodawany do tablicy dostawców kompresji wraz z dostawcą kompresji Gzip.
- Kompresja jest domyślnie kompresja Brotli, gdy skompresowany format danych Brotli jest obsługiwany przez klienta. Jeśli program Brotli nie jest obsługiwany przez klienta, kompresja jest domyślnie ustawiona na Gzip, gdy klient obsługuje kompresję Gzip.
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
}
Dostawca kompresji Brotli należy dodać, gdy wszyscy dostawcy kompresji są jawnie dodawani:
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" });
});
}
Ustaw poziom kompresji na BrotliCompressionProviderOptionswartość . Dostawca kompresji Brotli jest domyślnie na najszybszym poziomie kompresji (CompressionLevel.Fastest), który może nie produkować najbardziej wydajnej kompresji. Jeśli jest wymagana najbardziej wydajna kompresja, skonfiguruj oprogramowanie pośredniczące pod kątem optymalnej kompresji.
Poziom kompresji | opis |
---|---|
CompressionLevel.Fastest | Kompresja powinna zostać ukończona tak szybko, jak to możliwe, nawet jeśli wynikowe dane wyjściowe nie są optymalnie skompresowane. |
CompressionLevel.NoCompression | Nie należy wykonywać kompresji. |
CompressionLevel.Optimal | Odpowiedzi powinny być optymalnie skompresowane, nawet jeśli kompresja zajmuje więcej czasu. |
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.Configure<BrotliCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.Fastest;
});
}
Dostawca kompresji Gzip
Użyj polecenia , GzipCompressionProvider aby skompresować odpowiedzi z formatem pliku Gzip.
Jeśli żaden dostawca kompresji nie zostanie jawnie dodany do elementu CompressionProviderCollection:
- Dostawca kompresji Gzip jest domyślnie dodawany do tablicy dostawców kompresji wraz z dostawcą kompresji Brotli.
- Kompresja jest domyślnie kompresja Brotli, gdy skompresowany format danych Brotli jest obsługiwany przez klienta. Jeśli program Brotli nie jest obsługiwany przez klienta, kompresja jest domyślnie ustawiona na Gzip, gdy klient obsługuje kompresję Gzip.
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
}
Dostawca kompresji Gzip musi zostać dodany, gdy wszyscy dostawcy kompresji są jawnie dodawani:
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" });
});
}
Ustaw poziom kompresji na GzipCompressionProviderOptionswartość . Dostawca kompresji Gzip domyślnie do najszybszego poziomu kompresji (CompressionLevel.Fastest), który może nie produkować najbardziej wydajnej kompresji. Jeśli jest wymagana najbardziej wydajna kompresja, skonfiguruj oprogramowanie pośredniczące pod kątem optymalnej kompresji.
Poziom kompresji | opis |
---|---|
CompressionLevel.Fastest | Kompresja powinna zostać ukończona tak szybko, jak to możliwe, nawet jeśli wynikowe dane wyjściowe nie są optymalnie skompresowane. |
CompressionLevel.NoCompression | Nie należy wykonywać kompresji. |
CompressionLevel.Optimal | Odpowiedzi powinny być optymalnie skompresowane, nawet jeśli kompresja zajmuje więcej czasu. |
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.Configure<GzipCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.Fastest;
});
}
Dostawcy niestandardowi
Utwórz niestandardowe implementacje kompresji za pomocą polecenia ICompressionProvider. Obiekt EncodingName reprezentuje kodowanie zawartości, które powoduje wygenerowanie ICompressionProvider
. Oprogramowanie pośredniczące używa tych informacji do wybrania dostawcy na podstawie listy określonej w Accept-Encoding
nagłówku żądania.
Korzystając z przykładowej aplikacji, klient przesyła żądanie z nagłówkiem Accept-Encoding: mycustomcompression
. Oprogramowanie pośredniczące używa niestandardowej implementacji kompresji i zwraca odpowiedź z nagłówkiem Content-Encoding: mycustomcompression
. Aby implementacja kompresji niestandardowej działała, klient musi mieć możliwość dekompresowania niestandardowego kodowania.
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;
}
}
Prześlij żądanie do przykładowej aplikacji z nagłówkiem Accept-Encoding: mycustomcompression
i obserwuj nagłówki odpowiedzi. Nagłówki Vary
i Content-Encoding
znajdują się w odpowiedzi. Treść odpowiedzi (nie jest wyświetlana) nie jest kompresowana przez przykład. W klasie przykładu nie ma implementacji CustomCompressionProvider
kompresji. Jednak w przykładzie pokazano, gdzie można zaimplementować taki algorytm kompresji.
MIME, typy
Oprogramowanie pośredniczące określa domyślny zestaw typów MIME dla kompresji:
application/javascript
application/json
application/xml
text/css
text/html
text/json
text/plain
text/xml
Zastąp lub dołącz typy MIME opcjami oprogramowania pośredniczącego kompresji odpowiedzi. Należy pamiętać, że typy MIME z symbolami wieloznacznymi, takie jak text/*
nie są obsługiwane. Przykładowa aplikacja dodaje typ MIME dla image/svg+xml
i kompresuje i obsługuje obraz baneru 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" });
});
}
Kompresja z bezpiecznym protokołem
Skompresowane odpowiedzi za pośrednictwem bezpiecznych połączeń można kontrolować za pomocą EnableForHttps
opcji, która jest domyślnie wyłączona. Użycie kompresji z dynamicznie generowanymi stronami może prowadzić do problemów z zabezpieczeniami, takich jak CRIME i BREACH .
Dodawanie nagłówka Vary
Podczas kompresowania odpowiedzi na podstawie nagłówka Accept-Encoding
istnieje potencjalnie wiele skompresowanych wersji odpowiedzi i nieskompresowanej wersji. Aby poinstruować pamięć podręczną klienta i serwera proxy, że istnieje wiele wersji i powinny być przechowywane, Vary
nagłówek jest dodawany z wartością Accept-Encoding
. W programie ASP.NET Core 2.0 lub nowszym oprogramowanie pośredniczące automatycznie dodaje Vary
nagłówek po skompresowaniu odpowiedzi.
Problem z oprogramowaniem pośredniczącym w przypadku wystąpienia zwrotnego serwera proxy Nginx
Gdy żądanie jest proxied przez serwer Nginx, Accept-Encoding
nagłówek zostanie usunięty. Usunięcie nagłówka Accept-Encoding
uniemożliwia kompresowanie odpowiedzi przez oprogramowanie pośredniczące. Aby uzyskać więcej informacji, zobacz NGINX: kompresja i dekompresja. Ten problem jest śledzony przez rysunek kompresji przekazywania dla serwera Nginx (dotnet/aspnetcore#5989).
Praca z kompresją dynamiczną usług IIS
Jeśli masz aktywny moduł kompresji dynamicznej usług IIS skonfigurowany na poziomie serwera, który chcesz wyłączyć dla aplikacji, wyłącz moduł z dodatkiem do pliku web.config . Aby uzyskać więcej informacji, zobacz Wyłączanie modułów usług IIS.
Rozwiązywanie problemów
Użyj narzędzia, takiego jak Fiddler lub Firefox Browser Developer, które pozwala ustawić Accept-Encoding
nagłówek żądania i zbadać nagłówki odpowiedzi, rozmiar i treść. Domyślnie oprogramowanie pośredniczące kompresji odpowiedzi kompresuje odpowiedzi spełniające następujące warunki:
- Nagłówek
Accept-Encoding
jest obecny z wartościąbr
,gzip
,*
lub niestandardowego kodowania zgodnego z niestandardowym dostawcą kompresji, który został ustanowiony. Wartość nie może byćidentity
wartością jakości (qvalue,q
) ustawieniem 0 (zero). - Typ MIME (
Content-Type
) musi być ustawiony i musi być zgodny z typem MIME skonfigurowanym w obiekcie ResponseCompressionOptions. - Żądanie nie może zawierać nagłówka
Content-Range
. - Żądanie musi używać niezabezpieczonego protokołu (http), chyba że w opcjach oprogramowania pośredniczącego kompresji odpowiedzi skonfigurowano bezpieczny protokół (https). Zwróć uwagę na niebezpieczeństwo opisane powyżej podczas włączania bezpiecznej kompresji zawartości.