Antwortkomprimierung in ASP.NET Core

Die Netzwerkbandbreite ist eine begrenzte Ressource. Eine Reduzierung der Antwortgröße steigert in der Regel die Reaktionsfähigkeit einer App, häufig sogar erheblich. Eine Möglichkeit zum Verringern der Nutzlastgröße besteht darin, die Antworten aus einer Anwendung zu komprimieren. In diesem Artikel wird beschrieben, wie Sie die Reaktionskomprimierung für Ihre Apps mithilfe von Response Compression Middleware in ASP.NET Core implementieren.

Erkunden der Komprimierung mit HTTPS

Komprimierte Antworten über sichere Verbindungen können mithilfe der Option EnableForHttps gesteuert werden, die aus Sicherheitsgründen standardmäßig deaktiviert ist. Die Verwendung der Komprimierung bei dynamisch generierten Seiten kann die App für CRIME- und BREACH-Angriffe anfällig machen. CRIME- und BREACH-Angriffe können in ASP.NET Core durch fälschungssichere Token entschärft werden. Weitere Informationen finden Sie unter Prevent Cross-Site Request Forgery (XSRF/CSRF) Attacks in ASP.NET Core (Verhindern von websiteübergreifenden Anforderungsfälschungen (XSRF/CSRF) in ASP.NET Core). Informationen zur Abschwächung von BREACH Angriffen finden Sie unter Entschärfungen bei http://www.breachattack.com/.

Selbst wenn die App die Eigenschaft EnableForHttps (false) deaktiviert, können Internetinformationsdienste (IIS), IIS Express und Azure App ServiceGzip auf dem IIS-Webserver anwenden. Wenn Sie Antwortheader überprüfen, notieren Sie sich den Wert des Server-Headers. Ein unerwarteter content-encoding Antwortheaderwert kann das Ergebnis des Webservers und nicht die ASP.NET Core App-Konfiguration sein.

Ermitteln, wann die Middleware für die Reaktionskomprimierung verwendet werden soll

Verwenden Sie serverbasierte Technologien für die Antwortkomprimierung in IIS, Apache oder Nginx. Die Leistung der Middleware für die Reaktionskomprimierung kann wahrscheinlich nicht mit dem der Servermodule übereinstimmen. Der HTTP.sys Server und Kestrel Server bieten derzeit keine integrierte Komprimierungsunterstützung.

Verwenden Sie die Antwortkompressions-Middleware, wenn Folgendes auf die App zutrifft:

Erkunden der Reaktionskomprimierung

Normalerweise kann jede Antwort von einer Komprimierung profitieren, wenn sie nicht bereits nativ komprimiert ist. Nicht nativ komprimiert sind in der Regel CSS-, JavaScript-, HTML-, XML- und JSON-Antworten. Komprimieren Sie keine nativ komprimierten Inhalte, wie z. B. PNG-Dateien. Wenn Sie versuchen, eine systemeigene komprimierte Antwort weiter zu komprimieren, wird wahrscheinlich jede geringe zusätzliche Verringerung der Größe und Übertragungszeit durch die Zeit, die zum Verarbeiten der Komprimierung benötigt wird, überschattet. Komprimieren Sie dateien nicht kleiner als etwa 150 - 1.000 Bytes, je nach Inhalt der Datei und der Effizienz der Komprimierung. Der Aufwand beim Komprimieren kleiner Dateien kann eine komprimierte Datei erzeugen, die größer als die nicht komprimierte Datei ist.

Wenn ein Client komprimierte Inhalte verarbeiten kann, muss der Client den Server über seine Funktionen informieren, indem er den Accept-Encoding-Header mit der Anforderung sendet. Wenn ein Server komprimierten Inhalt sendet, muss er Informationen im Content-Encoding-Header enthalten, wie die komprimierte Antwort codiert wird.

Die folgende Tabelle zeigt die Inhaltscodierungsbezeichnungen für den Accept-Encoding Header und gibt an, ob die Middleware für die Reaktionskomprimierung die Bezeichnung unterstützt.

Bezeichnung Middleware Format Details
br Ja (Standard) Komprimiertes Brotli-Datenformat RFC 7932
deflate No DEFLATE-komprimiertes Datenformat RFC 1951
exi No Effizienter XML-Austausch (EXI) W3C-Empfehlung
gzip Yes Gzip-Dateiformat RFC 1952
identity Yes "Keine Codierung" – die Antwort darf nicht codiert werden. Problembehandlung bei der Reaktionskomprimierung
pack200-gzip No Netzwerkübertragungsformat für Java Archive JSR 200
* (Stern) Yes "Wildcard" – alle verfügbaren Inhaltscodierungen, die nicht explizit angefordert wurden Problembehandlung bei der Reaktionskomprimierung

Weitere Informationen finden Sie in der offiziellen IANA Content Coding List für HTTP-Parameter.

Die Middleware für die Reaktionskomprimierung ermöglicht das Hinzufügen anderer Komprimierungsanbieter für benutzerdefinierte Accept-Encoding Headerwerte. Weitere Informationen finden Sie weiter unten in diesem Artikel unter "Benutzerdefinierte Anbieter ".

Die Middleware für die Antwortkomprimierung ist in der Lage, auf die Gewichtung des Qualitätswerts (qvalue, q) zu reagieren, wenn dieser vom Client gesendet wird, um Komprimierungsverfahren zu priorisieren. Weitere Informationen finden Sie unter RFC 9110: HTTP-Semantik (Abschnitt 12.5.3 Accept-Encoding).

Bei Komprimierungsalgorithmen muss ein Kompromiss zwischen der Komprimierungsgeschwindigkeit und der Effektivität der Komprimierung gefunden werden. Effektivität bezieht sich in diesem Zusammenhang auf die Größe der Ausgabe nach der Komprimierung. Die kleinste Größe wird durch die optimale Komprimierung erreicht.

Die Header, die beim Anfordern, Senden, Zwischenspeichern und Empfangen von komprimierten Inhalten verwendet werden, werden in der folgenden Tabelle beschrieben.

Header Role Details
Accept-Encoding Wird vom Client an den Server gesendet, um die für den Client akzeptablen Inhaltscodierungsverfahren anzugeben. Accept-Encoding-Kopfzeile
Content-Encoding Wird vom Server an den Client gesendet, um die Inhaltscodierung der Nutzdaten anzugeben. Inhaltscodierungsheader
Content-Length Wenn die Komprimierung auftritt, wird der Content-Length Header entfernt, da sich der Textkörperinhalt ändert, wenn die Antwort komprimiert wird. Content-Length-Header
Content-MD5 Wenn die Komprimierung auftritt, wird die Content-MD5 Kopfzeile entfernt, da der Textkörperinhalt geändert wird und der Hash nicht mehr gültig ist. RFC 1864: Das Content-MD5-Headerfeld
Content-Type Gibt den MIME-Typ des Inhalts an. Jede Antwort sollte ihren Content-Type Wert angeben. Die Middleware für die Antwortkomprimierung überprüft anhand dieses Werts, ob die Antwort komprimiert werden soll. Die Middleware für die Reaktionskomprimierung gibt einen Satz von STANDARD-MIME-Typen an, die codiert werden können, und sie können ersetzt oder hinzugefügt werden. Inhaltstypheader
Vary Wenn der Server den Wert Accept-Encoding an Clients und Proxys sendet, zeigt der Vary-Header dem Client oder Proxy an, dass er Antworten basierend auf dem Accept-Encoding-Headerwert der Anforderung zwischenspeichern (variieren) soll. Die Rückgabe von Inhalten mit dem Vary: Accept-Encoding-Header hat zur Folge, dass sowohl komprimierte als auch nicht komprimierte Antworten separat zwischengespeichert werden. Kopfzeile variieren

Erkunden Sie die Features der Middleware für die Antwortkomprimierung mit der Beispiel-App. Das Beispiel veranschaulicht Folgendes:

  • Komprimierung von App-Antworten mithilfe von Gzip- und benutzerdefinierten Komprimierungsanbietern.
  • Vorgehensweise zum Hinzufügen eines MIME-Typs zur Standardliste der MIME-Typen für die Komprimierung
  • Vorgehensweise zum Hinzufügen eines benutzerdefinierten Anbieters für die Antwortkomprimierung

Konfigurieren der Middleware für die Reaktionskomprimierung

Der folgende Code zeigt, wie die Middleware zur Antwortkomprimierung für die standardmäßigen MIME-Typen und Komprimierungsanbieter (Brotli und Gzip) aktiviert werden kann:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
});

var app = builder.Build();

app.UseResponseCompression();

app.MapGet("/", () => "Hello World!");

app.Run();

Hinweise zur Antwortkomprimierungs-Middleware

Beachten Sie bei der Arbeit mit der Middleware für die Antwortkomprimierung die folgenden Punkte:

Senden Sie eine Anforderung ohne Accept-Encoding-Header an die Beispiel-App, und beachten Sie, dass die Antwort nicht komprimiert wird. Der Content-Encoding-Header ist nicht in der Sammlung der Antwortheader enthalten.

Gehen Sie z. B. in Firefox für Entwickler*innen so vor:

  1. Wählen Sie die Registerkarte „Netzwerk“ aus.
  2. Klicken Sie mit der rechten Maustaste auf die Anforderung in der Liste "Netzwerkanforderung ", und wählen Sie "Bearbeiten" aus, und senden Sie sie erneut.
  3. Ändern Sie den Wert von Accept-Encoding: von gzip, deflate, br in none.
  4. Wählen Sie "Senden" aus.

Senden Sie eine Anforderung an die Beispiel-App mit einem Browser mithilfe der Entwicklertools, und stellen Sie fest, dass die Antwort komprimiert ist. Die Content-Encoding- und Vary-Header sind in der Antwort enthalten.

Überprüfen von Anbietern

Dieser Abschnitt enthält Details zu Komprimierungsanbietern, einschließlich Brotli, Gzip und benutzerdefinierten Anbietern.

Komprimierungsanbieter Brotli und Gzip

Verwenden Sie die BrotliCompressionProvider Klasse, um Antworten mit RFC 7932 zu komprimieren: Brotli Compressed Data Format.

Wenn der Klasse keine Komprimierungsanbieter explizit hinzugefügtCompressionProviderCollection werden:

  • Standardmäßig werden die Brotli- und Gzip-Komprimierungsanbieter dem Array von Komprimierungsanbietern hinzugefügt.
  • Wenn der Client das Brotli-komprimierte Datenformat unterstützt, wird standardmäßig Brotli-Komprimierung verwendet.
  • Wenn der Client Brotli nicht unterstützt, wird standardmäßig Gzip komprimiert, wenn der Client die Gzip-Komprimierung unterstützt.

Wird ein Komprimierungsanbieter hinzugefügt, werden keine anderen Anbieter hinzugefügt. Wenn beispielsweise der Gzip-Komprimierungsanbieter der einzige explizit hinzugefügte Anbieter ist, werden keine weiteren Komprimierungsanbieter hinzugefügt.

Note

Dokumentationslinks zur .NET-Referenzquelle laden in der Regel den Standardbranch des Repositorys, der die aktuelle Entwicklung für das nächste Release von .NET darstellt. Um ein Tag für ein bestimmtes Release auszuwählen, verwenden Sie die Dropdownliste Switch branches or tags (Branches oder Tags wechseln). Weitere Informationen finden Sie unter How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Auswählen eines Versionstags von ASP.NET Core-Quellcode (dotnet/AspNetCore.Docs #26205)).

Der folgende Code:

  • Aktiviert die Antwortkomprimierung für HTTPS-Anforderungen.
  • Fügt die Antwortkomprimierungsanbieter Brotli und Gzip hinzu.
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();

Legen Sie die Komprimierungsebene mit der BrotliCompressionProviderOptions Klasse und GzipCompressionProviderOptions Klasse fest. Die Brotli- und Gzip-Komprimierungsanbieter haben standardmäßig die schnellste Komprimierungsebene, wie sie durch das "CompressionLevel.Fastest"-Enum bestimmt wird. Dieser Ansatz kann jedoch nicht die effizienteste Komprimierung erzeugen. Wenn eine möglichst effiziente Komprimierung gewünscht wird, konfigurieren Sie die Middleware zur Antwortkomprimierung für eine optimale Komprimierung.

Werte, die angeben, ob ein Komprimierungsvorgang die Geschwindigkeit oder Komprimierungsgröße betont, finden Sie unter "CompressionLevel Enum".

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

Benutzerdefinierte Anbieter

Erstellen Sie benutzerdefinierte Komprimierungsimplementierungen mit der ICompressionProvider Schnittstelle. Die EncodingName Eigenschaft stellt die von dieser ICompressionProvider Eigenschaft erzeugte Inhaltscodierung dar. Die Middleware für die Antwortkomprimierung verwendet diese Informationen, um den Anbieter anhand der in der im Accept-Encoding-Header der Anforderung angegebenen Liste auszuwählen.

Anforderungen an die Beispiel-App mit dem Accept-Encoding: mycustomcompression-Header geben eine Antwort mit einem Content-Encoding: mycustomcompression-Header zurück. Der Client muss in der Lage sein, die benutzerdefinierte Codierung zu dekomprimieren, damit eine benutzerdefinierte Komprimierungsimplementierung funktionieren kann.

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

Im vorherigen Code komprimiert das Beispiel den Antworttext nicht. Das Beispiel zeigt jedoch, wo ein benutzerdefinierter Komprimierungsalgorithmus implementiert werden kann.

Überprüfen der MIME-Typen

Die Middleware für die Antwortkomprimierung gibt einen Standardsatz von MIME-Typen für die Komprimierung an. Überprüfen Sie den Quellcode auf eine vollständige Liste der unterstützten MIME-Typen.

Note

Dokumentationslinks zur .NET-Referenzquelle laden in der Regel den Standardbranch des Repositorys, der die aktuelle Entwicklung für das nächste Release von .NET darstellt. Um ein Tag für ein bestimmtes Release auszuwählen, wählen Sie diesen mit der Dropdownliste Switch branches or tags (Branches oder Tags wechseln) aus. Weitere Informationen finden Sie unter How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Auswählen eines Versionstags von ASP.NET Core-Quellcode (dotnet/AspNetCore.Docs #26205)).

Ersetzen oder Anfügen von MIME-Typen durch die ResponseCompressionOptions.MimeTypes-Eigenschaft . Wildcard-MIME-Typen wie text/* werden nicht unterstützt. Die Beispiel-App fügt einen MIME-Typ für image/svg+xml hinzu und komprimiert und verarbeitet das ASP.NET Core-Bannerbild 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();

Kopfzeile "Vary" hinzufügen

Wenn Antworten basierend auf dem Accept-Encoding Anforderungsheader komprimiert werden, können möglicherweise sowohl nicht komprimierte als auch mehrere komprimierte Versionen der Antwort vorhanden sein. Um Client- und Proxycaches anzuweisen, dass mehrere Versionen vorhanden sind und gespeichert werden sollen, wird der Vary Header mit einem Accept-Encoding Wert hinzugefügt. Die Middleware der Antwort fügt den Header "Vary" in der ResponseCompressionBody.cs Datei automatisch hinzu, wenn die Antwort komprimiert wird.

Note

Dokumentationslinks zur .NET-Referenzquelle laden in der Regel den Standardbranch des Repositorys, der die aktuelle Entwicklung für das nächste Release von .NET darstellt. Um ein Tag für ein bestimmtes Release auszuwählen, wählen Sie diesen mit der Dropdownliste Switch branches or tags (Branches oder Tags wechseln) aus. Weitere Informationen finden Sie unter How to select a version tag of ASP.NET Core source code (dotnet/AspNetCore.Docs #26205) (Auswählen eines Versionstags von ASP.NET Core-Quellcode (dotnet/AspNetCore.Docs #26205)).

Probleme mit dem Nginx-Reverseproxy

Wenn Nginx die Anfrage weiterleitet, wird der Accept-Encoding-Header entfernt. Das Entfernen des Accept-Encoding-Headers verhindert, dass die Middleware für die Antwortkomprimierung die Antwort komprimiert. Weitere Informationen finden Sie unter Nginx: Komprimierung und Dekomprimierung. Dieses Problem wird in GitHub dotnet/aspnetcore issue #5989 - Figure out pass-through compression for Nginx nachverfolgt.

Deaktivieren der dynamischen IIS-Komprimierung

Informationen zum Deaktivieren des auf Serverebene konfigurierten IIS-Moduls für die dynamische Komprimierung finden Sie unter Deaktivieren von IIS-Modulen.

Problembehandlung bei der Antwortkomprimierung

Verwenden Sie ein Tool wie Firefox Browser – Developer Edition , mit dem Sie den Anforderungsheader Accept-Encoding festlegen und die Antwortheader, größe und textkörper untersuchen können. Standardmäßig komprimiert die Middleware für die Antwortkomprimierung Antworten, die die folgenden Bedingungen erfüllen:

  • Die Accept-Encoding Kopfzeile ist mit einem Wert von br, gzip, * (Sternchen) oder benutzerdefinierter Codierung vorhanden, die einem benutzerdefinierten Komprimierungsanbieter entspricht. Der Wert darf nicht identity (keine Codierung) sein oder einen Qualitätswert (qvalue, q) von 0 (Null) haben.

  • Der MIME-Typ (Content-Type) muss festgelegt werden und muss mit einem MIME-Typ übereinstimmen, der für die ResponseCompressionOptions Klasse konfiguriert ist.

  • Die Anforderung darf den Content-Range-Header nicht enthalten.

  • Die Anforderung muss das unsichere Hypertextprotokoll (http) verwenden, es sei denn, das sichere Hypertextprotokoll (https) ist in den Middleware-Optionen für die Reaktionskomprimierung konfiguriert.

    Important

    Überprüfen Sie die Risiken, die mit der Aktivierung der sicheren Inhaltskomprimierung verbunden sind, wie in der Komprimierung mit HTTPS weiter oben in diesem Artikel beschrieben.

Überprüfen des Azure bereitgestellten Beispiels

Die in Azure bereitgestellte Beispiel-App weist die folgende Datei Program.cs auf:

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

Die Netzwerkbandbreite ist eine begrenzte Ressource. Eine Reduzierung der Antwortgröße steigert in der Regel die Reaktionsfähigkeit einer App, häufig sogar erheblich. Eine Möglichkeit zum Verringern der Nutzdatengrößen besteht darin, die Antworten einer App zu komprimieren.

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Wann sollte Middleware zur Antwortkomprimierung verwendet werden?

Verwenden Sie serverbasierte Technologien für die Antwortkomprimierung in IIS, Apache oder Nginx. Die Leistung der Middleware entspricht wahrscheinlich nicht der Leistung der Servermodule. HTTP.sys-Server und Kestrel-Server bieten derzeit keine integrierte Komprimierungsunterstützung.

Verwenden Sie Middleware für die Antwortkomprimierung, wenn Folgendes zutrifft:

Antwortkomprimierung

Normalerweise kann jede Antwort von einer Komprimierung profitieren, wenn sie nicht bereits nativ komprimiert ist. Nicht nativ komprimiert sind in der Regel CSS-, JavaScript-, HTML-, XML- und JSON-Antworten. Sie sollten keine nativ komprimierten Inhalte komprimieren, wie z. B. PNG-Dateien. Wenn Sie versuchen, eine nativ komprimierte Antwort weiter zu komprimieren, wird jede noch so kleine zusätzliche Verringerung in Bezug auf Größe und Übertragungszeit wahrscheinlich durch die Zeit aufgehoben, die zur Verarbeitung der Komprimierung benötigt wird. Komprimieren Sie keine Dateien, die kleiner als etwa 150–1.000 Byte sind (je nach Inhalt der Datei und Effizienz der Komprimierung). Der Mehraufwand bei der Komprimierung kleiner Dateien kann dazu führen, dass die komprimierte Datei größer ist als die nicht komprimierte Datei.

Wenn ein Client komprimierte Inhalte verarbeiten kann, muss er den Server hierüber informieren, indem er den Accept-Encoding-Header mit der Anforderung sendet. Wenn ein Server komprimierte Inhalte sendet, muss er im Content-Encoding-Header angeben, wie die komprimierte Antwort codiert ist. Die von der Middleware unterstützten Inhaltscodierungsbezeichnungen sind in der folgenden Tabelle aufgeführt.

Accept-Encoding-Headerwerte Unterstützte Middleware Description
br Ja (Standard) Mit Brotli komprimiertes Datenformat
deflate No Mit DEFLATE komprimiertes Datenformat
exi No W3C Efficient XML Interchange
gzip Yes Gzip-Dateiformat
identity Yes Bezeichner „Keine Codierung“: Die Antwort darf nicht codiert werden.
pack200-gzip No Netzwerkübertragungsformat für Java-Archive
* Yes Alle verfügbaren Inhaltscodierungen, die nicht explizit angefordert wurden

Weitere Informationen finden Sie in der offiziellen Inhaltscodierungsliste der IANA.

Die Middleware ermöglicht es Ihnen, zusätzliche Komprimierungsanbieter für benutzerdefinierte Accept-Encoding-Headerwerte hinzuzufügen. Weitere Informationen finden Sie unter Benutzerdefinierte Anbieter weiter unten.

Die Middleware ist in der Lage, auf die Gewichtung des Qualitätswerts (qvalue, q) zu reagieren, wenn dieser vom Client gesendet wird, um Komprimierungsverfahren zu priorisieren. Weitere Informationen finden Sie unter RFC 9110: Accept-Encoding.

Bei Komprimierungsalgorithmen muss ein Kompromiss zwischen der Komprimierungsgeschwindigkeit und der Effektivität der Komprimierung gefunden werden. Effektivität bezieht sich in diesem Zusammenhang auf die Größe der Ausgabe nach der Komprimierung. Die kleinste Größe wird durch die optimale Komprimierung erreicht.

Die Header, die beim Anfordern, Senden, Zwischenspeichern und Empfangen von komprimierten Inhalten verwendet werden, werden in der Tabelle unten beschrieben.

Header Role
Accept-Encoding Wird vom Client an den Server gesendet, um die für den Client akzeptablen Inhaltscodierungsverfahren anzugeben.
Content-Encoding Wird vom Server an den Client gesendet, um die Inhaltscodierung der Nutzdaten anzugeben.
Content-Length Bei der Komprimierung wird der Content-Length-Header entfernt, da sich der Textinhalt ändert, wenn die Antwort komprimiert wird.
Content-MD5 Wenn eine Komprimierung stattfindet, wird der Content-MD5-Header entfernt, da sich der Textinhalt geändert hat und der Hash nicht länger gültig ist.
Content-Type Gibt den MIME-Typ des Inhalts an. In jeder Antwort sollte der Content-Type angegeben sein. Die Middleware überprüft anhand dieses Werts, ob die Antwort komprimiert werden soll. Die Middleware gibt einen Satz von Standard-MIME-Typen an, die sie codieren kann. Diese können jedoch ersetzt oder um weitere MIME-Typen ergänzt werden.
Vary Wenn der Server den Wert Accept-Encoding an Clients und Proxys sendet, zeigt der Vary-Header dem Client oder Proxy an, dass er Antworten basierend auf dem Accept-Encoding-Headerwert der Anforderung zwischenspeichern (variieren) soll. Die Rückgabe von Inhalten mit dem Vary: Accept-Encoding-Header hat zur Folge, dass sowohl komprimierte als auch nicht komprimierte Antworten separat zwischengespeichert werden.

Erkunden Sie die Features der Middleware für die Antwortkomprimierung mit der Beispiel-App. Das Beispiel veranschaulicht Folgendes:

  • Komprimierung von App-Antworten mithilfe von Gzip und benutzerdefinierten Komprimierungsanbietern
  • Vorgehensweise zum Hinzufügen eines MIME-Typs zur Standardliste der MIME-Typen für die Komprimierung

Configuration

Der folgende Code zeigt, wie die Middleware zur Antwortkomprimierung für die standardmäßigen MIME-Typen und Komprimierungsanbieter (Brotli und Gzip) aktiviert werden kann:

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

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

Notes:

  • app.UseResponseCompression muss vor jeglicher Middleware aufgerufen werden, die Antwortkompression durchführt. Weitere Informationen finden Sie unter ASP.NET Core-Middleware.
  • Verwenden Sie ein Tool wie Fiddler oder Firefox-Browser-Entwicklungstools, um den Accept-Encoding-Anforderungsheader festzulegen sowie Antwortheader, Größe und Text zu untersuchen.

Senden Sie eine Anforderung ohne Accept-Encoding-Header an die Beispiel-App, und beachten Sie, dass die Antwort nicht komprimiert wird. Die Content-Encoding- und Vary-Header sind nicht in der Antwort enthalten.

Fiddler-Fenster mit Anzeige des Ergebnisses einer Anforderung ohne Accept-Encoding-Header. Die Antwort ist nicht komprimiert.

Übermitteln Sie eine Anforderung mit Accept-Encoding: br-Header (Brotli-Komprimierung) an die Beispiel-App, und beachten Sie, dass die Antwort komprimiert wird. Die Content-Encoding- und Vary-Header sind in der Antwort enthalten.

Das Fiddler-Fenster zeigt das Ergebnis einer Anforderung mit dem Accept-Encoding-Header und dem Wert „br“. Der Vary- sowie der Content-Encoding-Header werden der Antwort hinzugefügt, die komprimiert ist.

Providers

Brotli-Komprimierungsanbieter

Verwenden Sie den BrotliCompressionProvider, um Antworten mit dem komprimierten Brotli-Datenformat zu komprimieren.

Wenn keine Komprimierungsanbieter explizit zu CompressionProviderCollection hinzugefügt werden:

  • Der Brotli-Komprimierungsanbieter wird standardmäßig zusammen mit dem Gzip-Komprimierungsanbieter dem Array der Komprimierungsanbieter hinzugefügt.
  • Die Komprimierung wird standardmäßig auf die Brotli-Komprimierung festgelegt, wenn das komprimierte Brotli-Datenformat vom Client unterstützt wird. Wenn Brotli vom Client nicht unterstützt wird, erfolgt die Komprimierung standardmäßig mit Gzip, sofern der Client die Gzip-Komprimierung unterstützt.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

Der Brotli-Komprimierungsanbieter muss hinzugefügt werden, sobald Komprimierungsanbieter explizit hinzugefügt werden.

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

Legen Sie den Komprimierungsgrad mit BrotliCompressionProviderOptions fest. Der Brotli-Komprimierungsanbieter verwendet standardmäßig den schnellsten Komprimierungsgrad (CompressionLevel.Fastest), der möglicherweise nicht die effizienteste Komprimierung liefert. Wenn eine möglichst effiziente Komprimierung gewünscht wird, konfigurieren Sie die Middleware für eine optimale Komprimierung.

Komprimierungsebene Description
CompressionLevel.Fastest Die Komprimierung soll so schnell wie möglich abgeschlossen werden, auch wenn die resultierende Ausgabe nicht optimal komprimiert ist.
CompressionLevel.NoCompression Es soll keine Komprimierung durchgeführt werden.
CompressionLevel.Optimal Die Antworten sollen optimal komprimiert werden, auch wenn die Komprimierung mehr Zeit in Anspruch nimmt.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

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

Gzip-Komprimierungsanbieter

Verwenden Sie den GzipCompressionProvider, um Antworten mit dem Gzip-Dateiformat zu komprimieren.

Wenn keine Komprimierungsanbieter explizit zu CompressionProviderCollection hinzugefügt werden:

  • Der Gzip-Komprimierungsanbieter wird standardmäßig zusammen mit dem Brotli-Komprimierungsanbieter dem Array der Komprimierungsanbieter hinzugefügt.
  • Die Komprimierung wird standardmäßig auf die Brotli-Komprimierung festgelegt, wenn das komprimierte Brotli-Datenformat vom Client unterstützt wird. Wenn Brotli vom Client nicht unterstützt wird, erfolgt die Komprimierung standardmäßig mit Gzip, sofern der Client die Gzip-Komprimierung unterstützt.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

Der Gzip-Komprimierungsanbieter ist erforderlich, wenn explizit Komprimierungsanbieter hinzugefügt werden.

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

Legen Sie den Komprimierungsgrad mit GzipCompressionProviderOptions fest. Der Gzip-Komprimierungsanbieter verwendet standardmäßig den schnellsten Komprimierungsgrad (CompressionLevel.Fastest), der möglicherweise nicht die effizienteste Komprimierung liefert. Wenn eine möglichst effiziente Komprimierung gewünscht wird, konfigurieren Sie die Middleware für eine optimale Komprimierung.

Komprimierungsebene Description
CompressionLevel.Fastest Die Komprimierung soll so schnell wie möglich abgeschlossen werden, auch wenn die resultierende Ausgabe nicht optimal komprimiert ist.
CompressionLevel.NoCompression Es soll keine Komprimierung durchgeführt werden.
CompressionLevel.Optimal Die Antworten sollen optimal komprimiert werden, auch wenn die Komprimierung mehr Zeit in Anspruch nimmt.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

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

Benutzerdefinierte Anbieter

Erstellen Sie mit ICompressionProvider benutzerdefinierte Implementierungen für die Komprimierung. EncodingName steht für die Inhaltscodierung, die dieser ICompressionProvider erzeugt. Die Middleware verwendet diese Informationen, um den Anbieter anhand der in der im Accept-Encoding-Header der Anforderung angegebenen Liste auszuwählen.

Bei Verwendung der Beispiel-App sendet der Client eine Anforderung mit dem Accept-Encoding: mycustomcompression-Header. Die Middleware verwendet die benutzerdefinierte Komprimierungsimplementierung und gibt die Antwort mit einem Content-Encoding: mycustomcompression-Header zurück. Der Client muss in der Lage sein, die benutzerdefinierte Codierung zu dekomprimieren, damit eine benutzerdefinierte Komprimierungsimplementierung funktionieren kann.

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

Senden Sie eine Anforderung mit Accept-Encoding: mycustomcompression-Header an die Beispiel-App, und überprüfen Sie die Antwortheader. Die Vary- und Content-Encoding-Header sind in der Antwort enthalten. Der Antworttext (nicht dargestellt) wird im Beispiel nicht komprimiert. Die Klasse CustomCompressionProvider des Beispiels enthält keine Komprimierungsimplementierung. Das Beispiel zeigt jedoch, wo Sie einen solchen Komprimierungsalgorithmus implementieren würden.

Fiddler-Fenster, das das Ergebnis einer Anforderung mit dem Accept-Encoding-Header und dem Wert „mycustomcompression“ anzeigt. Die Vary- und Content-Encoding-Header werden der Antwort hinzugefügt.

MIME-Typen

Die Middleware gibt einen Standardsatz von MIME-Typen für die Komprimierung an:

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

Anhand der Optionen für die Middleware zur Antwortkomprimierung können Sie MIME-Typen ersetzen oder anfügen. Beachten Sie, dass MIME-Typen mit Platzhaltern (wie z. B. text/*) nicht unterstützt werden. Die Beispiel-App fügt einen MIME-Typ für image/svg+xml hinzu und komprimiert und verarbeitet das ASP.NET Core-Bannerbild (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" });
    });
}

Komprimierung mit sicherem Protokoll

Komprimierte Antworten über sichere Verbindungen können mithilfe der Option EnableForHttps gesteuert werden, die standardmäßig deaktiviert ist. Die Verwendung der Komprimierung bei dynamisch generierten Seiten kann zu Sicherheitsproblemen führen und die App z. B. für CRIME- und BREACH-Angriffe anfällig machen.

Hinzufügen des Vary-Headers

Beim Komprimieren von Antworten basierend auf dem Accept-Encoding-Header kann es potenziell mehrere komprimierte Versionen der Antwort sowie eine unkomprimierte Version geben. Um den Client- und Proxycaches mitzuteilen, dass mehrere Versionen vorhanden sind und gespeichert werden sollen, wird der Vary-Header mit einem Accept-Encoding-Wert ergänzt. In ASP.NET Core 2.0 oder höher fügt die Middleware den Vary-Header automatisch hinzu, wenn die Antwort komprimiert wird.

Problem mit Middleware bei Verwendung hinter einem Nginx-Reverseproxy

Wird eine Anforderung durch einen Nginx-Proxy verarbeitet, wird der Accept-Encoding-Header entfernt. Das Entfernen des Accept-Encoding-Headers verhindert, dass die Middleware die Antwort komprimiert. Weitere Informationen finden Sie unter NGINX: Komprimierung und Dekomprimierung. Dieses Issue wird unter Ermitteln der Passthrough-Komprimierung für Nginx (dotnet/aspnetcore#5989) nachverfolgt.

Arbeiten mit der dynamischen IIS-Komprimierung

Wenn ein aktives Modul für die dynamische IIS-Komprimierung auf Serverebene konfiguriert wurde und Sie dieses für eine App deaktivieren möchten, deaktivieren Sie das Modul mit einem Zusatz in der Datei web.config. Weitere Informationen finden Sie unter Deaktivieren von IIS-Modulen.

Troubleshooting

Verwenden Sie ein Tool wie Fiddler oder die Firefox-Browser-Entwicklungstools, mit denen Sie den Accept-Encoding-Anforderungsheader festlegen sowie Antwortheader, Größe und Text untersuchen können. Standardmäßig komprimiert die Middleware für die Antwortkomprimierung Antworten, die die folgenden Bedingungen erfüllen:

  • Der Header Accept-Encoding weist einen Wert br, gzip, * oder eine benutzerdefinierte Codierung auf, die einem von Ihnen festgelegten benutzerdefinierten Komprimierungsanbieter entspricht. Der Wert darf nicht identity lauten oder einen Qualitätswert (qvalue, q) von 0 (Null) aufweisen.
  • Der MIME-Typ (Content-Type) muss festgelegt werden und mit einem der in ResponseCompressionOptions konfigurierten MIME-Typen übereinstimmen.
  • Die Anforderung darf nicht den Header Content-Range enthalten.
  • Die Anforderung muss ein unsicheres Protokoll (HTTP) verwenden – es sei denn, in den Optionen der Middleware für die Antwortkomprimierung ist ein sicheres Protokoll (HTTPS) konfiguriert. Beachten Sie die oben beschriebenen Risiken, wenn Sie die sichere Inhaltskomprimierung aktivieren.

Weitere Ressourcen