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 CRIMEBREACH 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:

Kompresja odpowiedzi

Zwykle każda odpowiedź nieskompresowana natywnie może korzystać z kompresji odpowiedzi. Odpowiedzi nie są kompresowane natywnie, zazwyczaj obejmują 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-Typewartość . 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:

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: z gzip, deflate, br na none.
  • 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).

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:

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-Typewartość . 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.

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

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.

Fiddler window showing result of a request with the Accept-Encoding header and a value of br. The Vary and Content-Encoding headers are added to the response. The response is compressed.

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.

Fiddler window showing result of a request with the Accept-Encoding header and a value of mycustomcompression. The Vary and Content-Encoding headers are added to the response.

MIME, 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.

Dodatkowe zasoby