Kompresi respons di ASP.NET Core

Bandwidth jaringan adalah sumber daya terbatas. Mengurangi ukuran respons biasanya meningkatkan respons aplikasi, sering kali secara dramatis. Salah satu cara untuk mengurangi ukuran payload adalah dengan mengompresi respons dari aplikasi. Artikel ini menjelaskan cara menerapkan kompresi respons untuk aplikasi Anda dengan menggunakan middleware kompresi respons di ASP.NET Core.

Menjelajahi kompresi dengan HTTPS

Respons terkompresi melalui koneksi aman dapat dikontrol dengan EnableForHttps opsi , yang dinonaktifkan secara default karena risiko keamanan. Menggunakan kompresi dengan halaman yang dihasilkan secara dinamis dapat mengekspos aplikasi ke CRIME dan BREACH serangan. CRIME dan BREACH serangan dapat dimitigasi di ASP.NET Core dengan menggunakan token anti-pemalsuan. Untuk informasi selengkapnya, lihat Mencegah serangan Pemalsuan Permintaan Antar Situs (XSRF/CSRF) di ASP.NET Core. Untuk informasi tentang mitigasi BREACH serangan, lihat Mitigasi di http://www.breachattack.com/.

Bahkan ketika aplikasi menonaktifkan properti EnableForHttps (false), Layanan Informasi Internet (IIS), IIS Express, dan Azure App Service dapat menerapkan Gzip di server web IIS. Saat Anda meninjau header respons, perhatikan nilai header Server . Nilai header respons content-encoding yang tidak terduga mungkin merupakan hasil dari server web dan bukan konfigurasi aplikasi ASP.NET Core.

Tentukan kapan harus menggunakan middleware kompresi respons

Gunakan teknologi kompresi respons berbasis server di IIS, Apache, atau Nginx. Performa middleware kompresi respons mungkin tidak akan sebanding dengan modul server. Server dan server Kestrel saat ini tidak menawarkan dukungan kompresi bawaan.

Gunakan middleware kompresi respons jika aplikasi:

Menjelajahi kompresi respons

Biasanya, respons apa pun yang tidak dikompresi secara asli dapat memperoleh manfaat dari kompresi respons. Respons yang tidak dikompresi secara asli biasanya mencakup CSS, JavaScript, HTML, XML, dan JSON. Jangan kompres aset yang dikompresi secara asli, seperti file PNG. Ketika mencoba untuk lebih memadatkan respons terkompresi asli, pengurangan ukuran ekstra kecil dan waktu transmisi kemungkinan dibayangi oleh waktu yang diperlukan untuk memproses kompresi. Jangan memadatkan file yang lebih kecil dari sekitar 150 - 1.000 byte, tergantung pada konten file dan efisiensi kompresi. Overhead mengompresi file kecil mungkin menghasilkan file terkompresi yang lebih besar dari file yang tidak dikompresi.

Ketika klien dapat memproses konten terkompresi, klien harus menginformasikan server kemampuannya dengan mengirim header Accept-Encoding dengan permintaan. Saat server mengirim konten terkompresi, server harus menyertakan informasi di header Pengodean Konten mengenai bagaimana respons terkompresi dikodekan.

Tabel berikut menunjukkan penunjukan pengodean konten untuk Accept-Encoding header dan menunjukkan apakah middleware kompresi respons mendukung penunjukan.

Penunjukan Middleware Rancangan Detail lebih lanjut
br Ya (default) Format Data Terkompresi Brotli RFC 7932
deflate No Format Data Terkompresi DEFLATE RFC 1951
exi No Pertukaran XML Yang Efisien (EXI) Rekomendasi W3C
gzip Yes Format file Gzip RFC 1952
identity Yes "Tidak ada pengodean" - respons tidak boleh dikodekan Memecahkan masalah kompresi respons
pack200-gzip No Format Transfer Jaringan untuk arsip Java JSR 200
* (tanda bintang) Yes "Wildcard" - pengkodean konten yang tersedia apa pun yang tidak diminta secara eksplisit Memecahkan masalah kompresi respons
Penunjukan Middleware Rancangan Detail lebih lanjut
br Ya (default) Format Data Terkompresi Brotli RFC 7932
deflate No Format Data Terkompresi DEFLATE RFC 1951
exi No Pertukaran XML Yang Efisien (EXI) Rekomendasi W3C
gzip Yes Format file Gzip RFC 1952
identity Yes "Tidak ada pengodean" - respons tidak boleh dikodekan Memecahkan masalah kompresi respons
pack200-gzip No Format Transfer Jaringan untuk arsip Java JSR 200
zstd Ya (default) Format Kompresi Data Zstandard RFC 8878
* (tanda bintang) Yes "Wildcard" - pengkodean konten yang tersedia apa pun yang tidak diminta secara eksplisit Memecahkan masalah kompresi respons

Untuk informasi selengkapnya, lihat IANA Official Content Coding List untuk parameter HTTP.

Middleware kompresi respons memungkinkan penambahan penyedia kompresi lain untuk nilai header kustom Accept-Encoding . Untuk informasi selengkapnya, lihat Penyedia Kustom nanti di artikel ini.

Middleware kompresi respons mampu bereaksi terhadap nilai kualitas (qvalue, q) pembobotan saat dikirim oleh klien untuk memprioritaskan skema kompresi. Untuk informasi selengkapnya, lihat RFC 9110: Semantik HTTP (Bagian 12.5.3 Accept-Encoding).

Algoritma kompresi tunduk pada tradeoff antara kecepatan kompresi dan efektivitas kompresi. Efektivitas dalam konteks ini mengacu pada ukuran output setelah pemadatan. Ukuran terkecil dicapai oleh kompresi optimal.

Header yang terlibat dalam mengajukan permohonan, mengirimkan, menyimpan sementara, dan menerima konten terkompresi dijelaskan dalam tabel berikut.

Header Role Detail lebih lanjut
Accept-Encoding Dikirim dari klien ke server untuk menunjukkan skema pengodean konten yang dapat diterima oleh klien. Header Accept-Encoding
Content-Encoding Dikirim dari server ke klien untuk menunjukkan pengodean konten dalam payload. Header 'Content-Encoding'
Content-Length Ketika pemadatan terjadi, Content-Length header dihapus karena konten isi berubah saat respons dikompresi. Header Panjang Konten
Content-MD5 Ketika pemadatan terjadi, Content-MD5 header dihapus karena konten isi diubah dan hash tidak lagi valid. RFC 1864: Bidang Header Content-MD5
Content-Type Menentukan tipe MIME dari konten. Setiap respons harus menentukan nilainya Content-Type . Middleware kompresi respons memeriksa nilai ini untuk menentukan apakah respons harus dikompresi. Middleware kompresi respons menentukan sekumpulan jenis MIME default yang dapat dikodekan, dan dapat diganti atau ditambahkan. Header Jenis Konten
Vary Ketika dikirim oleh server dengan nilai Accept-Encoding kepada klien dan proksi, header Vary menunjukkan kepada klien atau proksi bahwa mereka harus meng-cache respons dengan bervariasi berdasarkan nilai header Accept-Encoding dari permintaan. Hasil dari mengembalikan konten dengan Vary: Accept-Encoding header adalah bahwa respons terkompresi dan tidak dikompresi di-cache secara terpisah. Header bervariasi

Jelajahi fitur middleware kompresi respons dengan aplikasi sampel. Sampel mengilustrasikan:

  • Pemadatan respons aplikasi dengan menggunakan Gzip dan penyedia kompresi kustom.
  • Cara menambahkan jenis MIME ke daftar default jenis MIME untuk pemadatan.
  • Cara menambahkan penyedia kompresi respons kustom.

Konfigurasikan middleware kompresi respon

Kode berikut menunjukkan cara mengaktifkan middleware kompresi respons untuk jenis MIME default dan penyedia kompresi (Brotli dan Gzip):

Kode berikut menunjukkan cara mengaktifkan middleware kompresi respons untuk jenis MIME default dan penyedia kompresi (Brotli, Gzip, dan Zstandard):

Catatan tentang middleware kompresi respons

Saat Anda bekerja dengan middleware kompresi respons, ingatlah poin-poin berikut:

Kirim permintaan ke aplikasi sampel tanpa Accept-Encoding header dan amati bahwa respons tidak dikompresi. Header Content-Encoding tidak ada di koleksi Header Respons.

Misalnya, di Pengembang Firefox:

  1. Pilih tab jaringan.
  2. Klik kanan permintaan di daftar Permintaan jaringan dan pilih Edit dan kirim ulang.
  3. Ubah nilai Accept-Encoding: dari gzip, deflate, br menjadi none.
  4. Pilih Kirim.

Kirim permintaan ke aplikasi sampel dengan browser dengan menggunakan alat pengembang dan amati bahwa respons dikompresi. Header Content-Encoding dan Vary ada pada respons.

Meninjau penyedia

Bagian ini menyediakan detail tentang penyedia kompresi, termasuk Brotli, Gzip, dan penyedia kustom.

Bagian ini menyediakan detail tentang penyedia kompresi, termasuk Brotli, Gzip, Zstandard, dan penyedia kustom.

Penyedia kompresi Brotli dan Gzip

BrotliCompressionProvider Gunakan kelas untuk memadatkan respons dengan Format Data Terkompresi RFC 7932: Brotli.

Jika tidak ada penyedia kompresi yang secara eksplisit ditambahkan ke CompressionProviderCollection kelas :

  • Secara default, penyedia kompresi Brotli dan Gzip ditambahkan ke array penyedia kompresi.
  • Saat klien mendukung format data terkompresi Brotli, kompresi default ke kompresi Brotli.
  • Jika klien tidak mendukung Brotli, kompresi default ke Gzip saat klien mendukung kompresi Gzip.
  • Secara default, penyedia kompresi Brotli, Gzip, dan Zstandard ditambahkan ke array penyedia kompresi.
  • Saat klien mendukung format data terkompresi Zstandard, kompresi default ke kompresi Zstandard.
  • Jika klien tidak mendukung Zstandard tetapi mendukung Brotli, kompresi default ke kompresi Brotli.
  • Jika klien tidak mendukung Zstandard atau Brotli, kompresi default ke Gzip saat klien mendukung kompresi Gzip.

Saat penyedia kompresi ditambahkan, penyedia lain tidak ditambahkan. Misalnya, jika penyedia kompresi Gzip adalah satu-satunya penyedia yang ditambahkan secara eksplisit, tidak ada penyedia kompresi lain yang ditambahkan.

Note

Tautan dokumentasi ke sumber referensi .NET biasanya memuat cabang default repositori, yang mewakili pengembangan saat ini untuk rilis .NET berikutnya. Untuk memilih tag rilis tertentu, gunakan daftar dropdown Beralih cabang atau tag. Untuk informasi lebih lanjut, lihat Cara memilih tag versi kode sumber ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Kode berikut:

  • Mengaktifkan kompresi respons untuk permintaan HTTPS.
  • Menambahkan penyedia kompresi respons Brotli dan 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();

Atur tingkat kompresi dengan BrotliCompressionProviderOptions kelas dan GzipCompressionProviderOptions kelas. Penyedia kompresi Brotli dan Gzip default ke tingkat kompresi tercepat seperti yang ditentukan oleh enum CompressionLevel.Fastest . Namun, pendekatan ini mungkin tidak menghasilkan kompresi yang paling efisien. Jika kompresi yang paling efisien diinginkan, konfigurasikan middleware kompresi respons untuk pemadatan optimal.

Untuk nilai yang menunjukkan apakah operasi pemadatan menekankan kecepatan atau ukuran pemadatan, lihat Enum CompressionLevel.

using System.IO.Compression;
using Microsoft.AspNetCore.ResponseCompression;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
});

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

builder.Services.Configure<GzipCompressionProviderOptions>(options =>
{
    options.Level = CompressionLevel.SmallestSize;
});

var app = builder.Build();

app.UseResponseCompression();

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

app.Run();

Penyedia kompresi Zstandard

Gunakan kelas ZstandardCompressionProvider untuk mengompresi respons dengan RFC 8878: Kompresi Zstandard untuk HTTP.

Atur kualitas kompresi dengan ZstandardCompressionProviderOptions kelas . Tingkat kualitas Zstandard berkisar dari 1 hingga 22, di mana nilai yang lebih tinggi menghasilkan kompresi yang lebih baik tetapi kecepatan yang lebih lambat. Contoh berikut menetapkan kualitas kompresi Zstandard:

builder.Services.Configure<ZstandardCompressionProviderOptions>(options =>
{
    options.CompressionOptions = new ZstandardCompressionOptions
    {
        Quality = 6 // 1 to 22, higher = better compression, slower
    };
});

Penyedia kustom

Buat implementasi kompresi kustom dengan ICompressionProvider antarmuka. Properti EncodingName mewakili pengkodean konten yang dihasilkan oleh ICompressionProvider ini. Middleware kompresi respons menggunakan informasi ini untuk memilih penyedia berdasarkan daftar yang ditentukan di Accept-Encoding header permintaan.

Permintaan ke aplikasi sampel dengan header Accept-Encoding: mycustomcompression mengembalikan respon dengan header Content-Encoding: mycustomcompression. Klien harus dapat mendekompresi pengodean kustom agar implementasi kompresi kustom berfungsi.

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

Dalam kode sebelumnya, contoh tersebut tidak mengompres isi respons. Namun, sampel menunjukkan tempat menerapkan algoritma kompresi kustom.

Meninjau jenis MIME

Middleware kompresi respons menentukan sekumpulan jenis MIME default untuk pemadatan. Tinjau kode sumber untuk daftar lengkap jenis MIME yang didukung.

Note

Tautan dokumentasi ke sumber referensi .NET biasanya memuat cabang default repositori, yang mewakili pengembangan saat ini untuk rilis .NET berikutnya. Untuk memilih tag rilis tertentu, gunakan daftar dropdown Beralih cabang atau tag. Untuk informasi lebih lanjut, lihat Cara memilih tag versi kode sumber ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Ganti atau tambahkan jenis MIME dengan properti ResponseCompressionOptions.MimeTypes . Jenis MIME wildcard seperti text/* tidak didukung. Aplikasi sampel menambahkan jenis MIME untuk image/svg+xml dan memadatkan serta menyajikan gambar banner 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();

Tambahkan header Vary

Ketika respons dikompresi berdasarkan tajuk permintaan Accept-Encoding, mungkin ada respons yang tidak dikompresi dan beberapa versi respons yang dikompresi. Untuk menginstruksikan cache klien dan proksi bahwa beberapa versi ada dan harus disimpan, tajuk Vary ditambahkan dengan nilai Accept-Encoding. Middleware respons menambahkan header 'Vary' di file ResponseCompressionBody.cs secara otomatis saat respons dikompresi.

Note

Tautan dokumentasi ke sumber referensi .NET biasanya memuat cabang default repositori, yang mewakili pengembangan saat ini untuk rilis .NET berikutnya. Untuk memilih tag rilis tertentu, gunakan daftar dropdown Beralih cabang atau tag. Untuk informasi lebih lanjut, lihat Cara memilih tag versi kode sumber ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Masalah dengan proksi terbalik Nginx

Ketika Nginx memproksi permintaan, Accept-Encoding header dihapus. Penghapusan header Accept-Encoding mencegah middleware kompresi respons mengompres respons. Untuk informasi selengkapnya, lihat Nginx: Kompresi dan dekompresi. Masalah ini dilacak dalam GitHub dotnet/aspnetcore issue #5989 - Menemukan kompresi pass-through untuk Nginx.

Menonaktifkan kompresi dinamis IIS

Untuk menonaktifkan Modul Kompresi Dinamis IIS yang dikonfigurasi di tingkat server, lihat Menonaktifkan modul IIS.

Mengatasi masalah kompresi respons

Gunakan alat seperti Firefox Browser - Edisi pengembang yang memungkinkan Anda mengatur Accept-Encoding header permintaan dan mempelajari header, ukuran, dan isi respons. Secara default, middleware kompresi respons mengompresi respons yang memenuhi kondisi berikut:

  • Header Accept-Encoding hadir dengan nilai br, , gzip* (tanda bintang), atau pengodean kustom yang cocok dengan penyedia kompresi kustom. Nilai tidak boleh identity (tidak ada pengodean) atau memiliki pengaturan nilai kualitas (qvalue, q) sebesar 0 (nol).
  • Header Accept-Encoding hadir dengan nilai br, , gzip, zstd* (tanda bintang), atau pengodean kustom yang cocok dengan penyedia kompresi kustom. Nilai tidak boleh identity (tidak ada pengodean) atau memiliki pengaturan nilai kualitas (qvalue, q) sebesar 0 (nol).
  • Jenis MIME (Content-Type) harus diatur dan harus cocok dengan jenis MIME yang dikonfigurasi pada ResponseCompressionOptions kelas.

  • Permintaan tidak boleh menyertakan header Content-Range.

  • Permintaan harus menggunakan protokol hiperteks yang tidak aman (http), kecuali protokol hiperteks aman (https) dikonfigurasi dalam opsi middleware kompresi respons.

    Important

    Tinjau risiko yang terkait dengan pengaktifan kompresi konten aman, seperti yang dijelaskan dalam Kompresi dengan HTTPS sebelumnya di artikel ini.

Tinjau sampel yang diterapkan di Azure

Aplikasi sampel yang disebarkan ke Azure memiliki file Program.cs berikut:

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

Bandwidth jaringan adalah sumber daya terbatas. Mengurangi ukuran respons biasanya meningkatkan respons aplikasi, sering kali secara dramatis. Salah satu cara untuk mengurangi ukuran payload adalah dengan mengompresi respons aplikasi.

Melihat atau mengunduh kode sampel (cara mengunduh)

Kapan menggunakan middleware kompresi respons

Gunakan teknologi kompresi respons berbasis server di IIS, Apache, atau Nginx. Performa middleware mungkin tidak akan cocok dengan modul server. HTTP.sys server dan Kestrel server saat ini tidak menawarkan dukungan kompresi bawaan.

Gunakan middleware kompresi respons saat Anda:

Kompresi respons

Biasanya, respons apa pun yang tidak dikompresi secara asli dapat memperoleh manfaat dari kompresi respons. Respons yang tidak dikompresi secara asli biasanya meliputi: CSS, JavaScript, HTML, XML, dan JSON. Anda tidak boleh mengompresi aset terkompresi asli, seperti file PNG. Jika Anda mencoba untuk mengompres lebih lanjut respons yang sudah terkompresi, setiap pengurangan tambahan dalam ukuran dan waktu transmisi kemungkinan akan diabaikan karena waktu yang dihabiskan untuk memproses kompresi. Jangan memadatkan file yang lebih kecil dari sekitar 150-1000 byte (tergantung pada konten file dan efisiensi kompresi). Overhead mengompresi file kecil dapat menghasilkan file terkompresi yang lebih besar dari file yang tidak dikompresi.

Ketika klien dapat memproses konten terkompresi, klien harus menginformasikan server kemampuannya dengan mengirim Accept-Encoding header dengan permintaan. Saat server mengirim konten terkompresi, server harus menyertakan informasi di Content-Encoding header tentang bagaimana respons terkompresi dikodekan. Penetapan pengodean konten yang didukung oleh middleware diperlihatkan dalam tabel berikut.

Accept-Encoding nilai header Middleware didukung Description
br Ya (default) Format data terkompresi Brotli
deflate No Format data terkompresi DEFLATE
exi No Pertukaran XML Efisien W3C
gzip Yes Format file Gzip
identity Yes Pengidentifikasi "Tanpa pengodean": Respons tidak boleh dikodekan.
pack200-gzip No Format Pengiriman Jaringan untuk Arsip Java
* Yes Pengodean konten yang tersedia tidak diminta secara eksplisit

Untuk informasi selengkapnya, lihat Daftar Pengodean Konten Resmi IANA.

Middleware memungkinkan Anda menambahkan penyedia kompresi tambahan untuk nilai header kustom Accept-Encoding . Untuk informasi selengkapnya, lihat Penyedia Kustom di bawah ini.

Middleware mampu bereaksi terhadap pembobotan nilai kualitas (qvalue, q) saat dikirim oleh klien untuk memprioritaskan skema kompresi. Untuk informasi selengkapnya, lihat RFC 9110: Accept-Encoding.

Algoritma kompresi tunduk pada tradeoff antara kecepatan kompresi dan efektivitas kompresi. Efektivitas dalam konteks ini mengacu pada ukuran output setelah pemadatan. Ukuran terkecil dicapai oleh kompresi yang paling optimal .

Header yang terlibat dalam meminta, mengirim, membuat cache, dan menerima konten terkompresi dijelaskan dalam tabel di bawah ini.

Header Role
Accept-Encoding Dikirim dari klien ke server untuk menunjukkan skema pengodean konten yang dapat diterima oleh klien.
Content-Encoding Dikirim dari server ke klien untuk menunjukkan pengodean konten dalam payload.
Content-Length Ketika pemadatan terjadi, Content-Length header dihapus, karena konten isi berubah saat respons dikompresi.
Content-MD5 Ketika pemadatan terjadi, Content-MD5 header dihapus, karena konten isi telah berubah dan hash tidak lagi valid.
Content-Type Menentukan tipe MIME konten. Setiap respons harus menentukan Content-Type. Middleware memeriksa nilai ini untuk menentukan apakah respons harus dikompresi. Middleware menentukan sekumpulan jenis MIME default yang dapat dikodekan, tetapi Anda dapat mengganti atau menambahkan jenis MIME.
Vary Ketika dikirim oleh server dengan nilai Accept-Encoding kepada klien dan proksi, header Vary menunjukkan kepada klien atau proksi bahwa mereka harus meng-cache respons dengan bervariasi berdasarkan nilai header Accept-Encoding dari permintaan. Hasil dari mengembalikan konten dengan Vary: Accept-Encoding header adalah bahwa respons terkompresi dan tidak dikompresi di-cache secara terpisah.

Jelajahi fitur middleware kompresi respons dengan aplikasi sampel. Sampel mengilustrasikan:

  • Pemadatan respons aplikasi menggunakan Gzip dan penyedia kompresi kustom.
  • Cara menambahkan jenis MIME ke daftar default jenis MIME untuk pemadatan.

Configuration

Kode berikut menunjukkan cara mengaktifkan middleware kompresi respons untuk jenis MIME default dan penyedia kompresi (Brotli dan Gzip):

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

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

Notes:

  • app.UseResponseCompression harus dipanggil sebelum middleware apa pun yang mengompresi respons. Untuk informasi selengkapnya, lihat ASP.NET Core middleware.
  • Gunakan alat seperti Fiddler, Pengembang Browser Firefox untuk mengatur Accept-Encoding header permintaan dan mempelajari header respons, ukuran, dan isi.

Kirim permintaan ke aplikasi sampel tanpa Accept-Encoding header dan amati bahwa respons tidak dikompresi. Header Content-Encoding dan Vary tidak ada pada respons.

Jendela Fiddler memperlihatkan hasil permintaan tanpa header Accept-Encoding. Respons tidak dikompresi.

Kirim permintaan ke aplikasi sampel dengan Accept-Encoding: br header (kompresi Brotli) dan amati bahwa respons dikompresi. Header Content-Encoding dan Vary ada pada respons.

Jendela Fiddler memperlihatkan hasil permintaan dengan header Accept-Encoding dan nilai br. Header Vary dan Content-Encoding ditambahkan ke respons. Respons dikompresi.

Providers

Penyedia Kompresi Brotli

Gunakan BrotliCompressionProvider untuk memadatkan respons dengan format data terkompresi Brotli.

Jika tidak ada penyedia kompresi yang secara eksplisit ditambahkan ke CompressionProviderCollection:

  • Penyedia Kompresi Brotli ditambahkan secara default ke array penyedia kompresi bersama dengan penyedia kompresi Gzip.
  • Kompresi menggunakan Brotli secara default ketika format data terkompresi Brotli didukung oleh klien. Jika Brotli tidak didukung oleh klien, kompresi default ke Gzip saat klien mendukung kompresi Gzip.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

Penyedia Kompresi Brotli harus ditambahkan ketika penyedia kompresi apa pun ditambahkan secara eksplisit.

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

Atur tingkat kompresi dengan BrotliCompressionProviderOptions. Penyedia Kompresi Brotli default ke tingkat kompresi tercepat (CompressionLevel.Fastest), yang mungkin tidak menghasilkan kompresi yang paling efisien. Jika kompresi yang paling efisien diinginkan, konfigurasikan middleware untuk pemadatan optimal.

Tingkat Pemadatan Description
CompressionLevel.Fastest Pemadatan harus selesai secepat mungkin, bahkan jika output yang dihasilkan tidak dikompresi secara optimal.
CompressionLevel.NoCompression Tidak ada kompresi yang harus dilakukan.
CompressionLevel.Optimal Respons harus dikompresi secara optimal, bahkan jika kompresi membutuhkan lebih banyak waktu untuk diselesaikan.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

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

Penyedia Kompresi Gzip

GzipCompressionProvider Gunakan untuk mengompresi respons dengan format file Gzip.

Jika tidak ada penyedia kompresi yang secara eksplisit ditambahkan ke CompressionProviderCollection:

  • Penyedia Kompresi Gzip ditambahkan secara default ke array penyedia kompresi bersama dengan Penyedia Kompresi Brotli.
  • Kompresi menggunakan Brotli secara default ketika format data terkompresi Brotli didukung oleh klien. Jika Brotli tidak didukung oleh klien, kompresi default ke Gzip saat klien mendukung kompresi Gzip.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

Penyedia Kompresi Gzip harus ditambahkan ketika setiap penyedia kompresi ditambahkan dengan eksplisit.

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

Atur tingkat kompresi dengan GzipCompressionProviderOptions. Penyedia Kompresi Gzip default ke tingkat kompresi tercepat (CompressionLevel.Fastest), yang mungkin tidak menghasilkan kompresi yang paling efisien. Jika kompresi yang paling efisien diinginkan, konfigurasikan middleware untuk pemadatan optimal.

Tingkat Pemadatan Description
CompressionLevel.Fastest Pemadatan harus selesai secepat mungkin, bahkan jika output yang dihasilkan tidak dikompresi secara optimal.
CompressionLevel.NoCompression Tidak ada kompresi yang harus dilakukan.
CompressionLevel.Optimal Respons harus dikompresi secara optimal, bahkan jika kompresi membutuhkan lebih banyak waktu untuk diselesaikan.
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

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

Penyedia kustom

Buat implementasi kompresi kustom dengan ICompressionProvider. EncodingName mewakili pengodean konten yang dihasilkan oleh ICompressionProvider. Middleware menggunakan informasi ini untuk memilih penyedia berdasarkan daftar yang ditentukan di Accept-Encoding header permintaan.

Dengan menggunakan aplikasi sampel, klien mengirimkan permintaan dengan header Accept-Encoding: mycustomcompression. Middleware menggunakan implementasi kompresi kustom dan mengembalikan respons dengan Content-Encoding: mycustomcompression header. Klien harus dapat mendekompresi pengodean kustom agar implementasi kompresi kustom berfungsi.

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

Kirim permintaan ke aplikasi sampel dengan Accept-Encoding: mycustomcompression header dan amati header respons. Header Vary dan Content-Encoding ada pada respons. Isi respons (tidak ditampilkan) tidak dikompresi oleh sampel. Tidak ada implementasi kompresi di CustomCompressionProvider kelas sampel. Namun, sampel menunjukkan di mana Anda akan menerapkan algoritma kompresi seperti itu.

Jendela Fiddler menunjukkan hasil suatu permintaan dengan header Accept-Encoding dan nilai mycustomcompression. Header Vary dan Content-Encoding ditambahkan ke respons.

Jenis MIME

Middleware menentukan sekumpulan jenis MIME default untuk pemadatan:

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

Ganti atau tambahkan jenis MIME dengan opsi middleware kompresi respons. Perhatikan bahwa jenis MIME wildcard, seperti text/* tidak didukung. Aplikasi sampel menambahkan jenis MIME untuk image/svg+xml dan memadatkan dan menyajikan gambar banner 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" });
    });
}

Pemadatan dengan protokol aman

Respons terkompresi melalui koneksi aman dapat dikontrol dengan EnableForHttps opsi , yang dinonaktifkan secara default. Menggunakan kompresi dengan halaman yang dihasilkan secara dinamis dapat menyebabkan masalah keamanan seperti serangan CRIME dan serangan BREACH.

Tambahkan header Vary

Saat mengompresi respons berdasarkan Accept-Encoding header, berpotensi ada beberapa versi respons yang dikompresi dan versi yang tidak dikompresi. Untuk menginstruksikan cache klien dan proksi bahwa beberapa versi ada dan harus disimpan, header Vary ditambahkan dengan nilai Accept-Encoding. Di ASP.NET Core 2.0 atau yang lebih baru, middleware menambahkan Vary header secara otomatis saat respons dikompresi.

Masalah middleware saat menggunakan proksi terbalik Nginx

Ketika permintaan diproksi oleh Nginx, Accept-Encoding header dihapus. Penghapusan header Accept-Encoding mencegah middleware mengompresi respons. Untuk informasi selengkapnya, lihat NGINX: Pemadatan dan Dekompresi. Masalah ini dilacak oleh Cari tahu kompresi pass-through untuk Nginx (dotnet/aspnetcore#5989).

Bekerja dengan kompresi dinamis IIS

Jika Anda memiliki Modul Kompresi Dinamis IIS aktif yang dikonfigurasi di tingkat server yang ingin Anda nonaktifkan untuk aplikasi, nonaktifkan modul dengan tambahan ke file web.config . Untuk informasi selengkapnya, lihat Menonaktifkan modul IIS.

Troubleshooting

Gunakan alat seperti Fiddler atau Firefox Browser Developer, yang memungkinkan Anda mengatur Accept-Encoding header permintaan dan mempelajari header, ukuran, dan isi respons. Secara default, middleware kompresi respons mengompresi respons yang memenuhi kondisi berikut:

  • Header Accept-Encoding hadir dengan nilai br, , gzip, *atau pengodean kustom yang cocok dengan penyedia kompresi kustom yang telah Anda tetapkan. Nilai tidak boleh identity atau memiliki pengaturan nilai kualitas (qvalue, q) dengan pengaturan 0 (nol).
  • Jenis MIME (Content-Type) harus diatur dan harus cocok dengan jenis MIME yang dikonfigurasi pada ResponseCompressionOptions.
  • Permintaan tidak boleh menyertakan Content-Range header.
  • Permintaan harus menggunakan protokol yang tidak aman (http), kecuali protokol aman (https) dikonfigurasi dalam opsi middleware kompresi respons. Perhatikan bahaya yang dijelaskan di atas saat mengaktifkan pemadatan konten aman.

Sumber daya tambahan