ASP.NET Core 中的回應壓縮

網路頻寬是有限的資源。 減少回應的大小通常會增加應用程式的回應性,且通常會大幅提高。 減少承載大小的其中一種方法是壓縮應用程式的回應。

使用 HTTPS 進行壓縮

可以使用 EnableForHttps 選項 (由於存在安全性風險,此選項預設為停用) 來控制安全連線上的壓縮回應。 對動態產生的頁面使用壓縮可能會讓應用程式暴露遭受 CRIMEBREACH 攻擊的風險。 可以在 ASP.NET Core 中使用防偽權杖來減少遭受 CRIME 和 BREACH 攻擊的風險。 如需詳細資訊,請參閱防止 ASP.NET Core 中的跨網站要求偽造 (XSRF/CSRF) 攻擊。 如需減少遭受 BREACH 攻擊風險的相關資訊,請參閱風險降低 (網址:http://www.breachattack.com/)

即使在應用程式中停用 EnableForHttps,IIS、IIS Express 和 Azure App Service 仍可在 IIS Web 伺服器上套用 gzip。 檢閱回應標頭時,請記下 Server 值。 非預期的 content-encoding 回應標頭值可能是 Web 伺服器的結果,而不是 ASP.NET Core 應用程式設定的結果。

何時使用回應壓縮中介軟體

在 IIS、Apache 或 Nginx 中使用伺服器型的回應壓縮技術。 回應壓縮中介軟體的效能可能不符合伺服器模組的效能。 HTTP.sys 伺服器和 Kestrel 伺服器目前不提供內建的壓縮支援。

當應用程式處於以下情況時,請使用「回應壓縮中介軟體」:

回應壓縮

通常,任何原本未壓縮的回應都可以從回應壓縮中受益。 原本未壓縮的回應通常包括 CSS、JavaScript、HTML、XML 和 JSON。 不要壓縮原本已壓縮的資產 (例如 PNG 檔案)。 嘗試進一步壓縮原本已壓縮的回應時,任何大小和傳輸時間的微小額外減少量都可能會被處理壓縮所需的時間所掩蓋。 不要壓縮小於 150-1000 個位元組的檔案 (根據檔案的內容和壓縮的效率而定)。 壓縮小型檔案的額外工作可能會產生比未壓縮檔案更大的壓縮檔。

當用戶端可以處理壓縮的內容時,用戶端必須透過隨要求傳送 Accept-Encoding 標頭來告知伺服器其能力。 當伺服器傳送壓縮內容時,它必須在 Content-Encoding 標頭中包含有關如何對壓縮回應進行編碼的資訊。 下表顯示回應壓縮中介軟體所支援的內容編碼指定。

Accept-Encoding 標頭值 受中介軟體支援 描述
br 是 (預設) Brotli 壓縮資料格式
deflate No DEFLATE 壓縮資料格式
exi No W3C 高效 XML 交換
gzip Yes GZIP 檔案格式
identity Yes 「無編碼」識別碼:回應不得編碼。
pack200-gzip No JAVA 封存的網路傳輸格式
* Yes 未明確要求的任何可用內容編碼

如需詳細資訊,請參閱 IANA 官方內容編碼清單

回應壓縮中介軟體允許為自訂 Accept-Encoding 標頭值新增其他的壓縮提供者。 如需詳細資訊,請參閱本文中的自訂提供者

回應壓縮中介軟體能夠在用戶端傳送品質值 (qvalue, q) 權重時對其做出反應,以設定壓縮配置的優先順序。 如需詳細資訊,請參閱 RFC 9110: Accept-Encoding

壓縮演算法需要在壓縮速度和壓縮有效性之間進行取捨。 此內容中的有效性是指壓縮後的輸出大小。 最小的大小是透過最佳壓縮來獲得的。

下表說明要求、傳送、快取和接收壓縮內容所涉及的標頭。

標題 角色
Accept-Encoding 從用戶端傳送至伺服器,以指出用戶端可接受的內容編碼配置。
Content-Encoding 從伺服器傳送至用戶端,以指出承載中的內容編碼。
Content-Length 發生壓縮時,Content-Length 標頭會被移除,因為壓縮回應時本文內容改變了。
Content-MD5 發生壓縮時,Content-MD5 標頭會被移除,因為本文內容已改變且雜湊值不再有效。
Content-Type 指定內容的 MIME 類型。 每個回應都應指定其 Content-Type。 回應壓縮中介軟體會檢查此值,以判斷是否應壓縮回應。 回應壓縮中介軟體會指定一組它可編碼的預設 MIME 類型,而且可以取代或新增它們。
Vary 當伺服器以 Accept-Encoding 的值傳送至用戶端和 Proxy 時,Vary 標頭會向用戶端或 Proxy 指示它應該根據要求的 Accept-Encoding 標頭的值來快取 (改變) 回應。 使用 Vary: Accept-Encoding 標頭傳回內容的結果是,壓縮和未壓縮的回應都會被分別快取。

透過範例應用程式來探索「回應壓縮中介軟體」的功能。 該範例說明:

  • 使用 Gzip 和自訂壓縮提供者來壓縮應用程式回應。
  • 如何將 MIME 類型新增至預設的 MIME 類型清單中以進行壓縮。
  • 如何新增自訂回應壓縮提供者。

組態

下列程式碼示範如何為預設 MIME 類型和壓縮提供者 (BrotliGzip) 啟用「回應壓縮中介軟體」:

var builder = WebApplication.CreateBuilder(args);

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

var app = builder.Build();

app.UseResponseCompression();

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

app.Run();

注意:

對範例應用程式提交不含 Accept-Encoding 標頭的要求,並觀察回應是否未壓縮。 Content-Encoding 標頭不在「回應標頭」集合中。

例如,在 Firefox Developer 中:

  • 選取 [網路] 索引標籤。
  • 以滑鼠右鍵按一下 [網路要求清單] 中的要求,然後選取 [編輯並重新傳送
  • Accept-Encoding:gzip, deflate, br 變更為 none
  • 請選取傳送

使用開發人員工具透過瀏覽器對範例應用程式提交要求,並觀察回應是否已壓縮。 Content-EncodingVary 標頭會出現在回應中。

提供者

Brotli 和 Gzip 壓縮提供者

使用 BrotliCompressionProvider 來以 Brotli 壓縮資料格式壓縮回應。

如果未明確將壓縮提供者新增CompressionProviderCollection,則:

  • Brotli 壓縮提供者和 Gzip 壓縮提供者依預設會新增至壓縮提供者的陣列中。
  • 當用戶端支援 Brotli 壓縮的資料格式時,壓縮會預設為 Brotli 壓縮。 如果用戶端不支援 Brotli,則當用戶端支援 Gzip 壓縮時,壓縮會預設為 Gzip。

注意

.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

新增某一個壓縮提供者時後,便不會再新增其他的提供者。 例如,如果 Gzip 壓縮提供者是唯一明確新增的提供者,則不會再新增其他的壓縮提供者。

下列程式碼範例:

  • 對 HTTPS 要求啟用回應壓縮。
  • 新增了 Brotli 和 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();

使用 BrotliCompressionProviderOptionsGzipCompressionProviderOptions 設定壓縮層級。 Brotli 和 Gzip 壓縮提供者預設為最快的壓縮層級: CompressionLevel.Fastest (這可能不會產生最有效率的壓縮)。 如果想要最有效率的壓縮,請設定回應壓縮中介軟體以獲得最佳的壓縮。

如需指出壓縮作業強調速度或壓縮大小的值,請參閱 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();

自訂提供者

使用 ICompressionProvider 建立自訂壓縮實作。 EncodingName 代表這個 ICompressionProvider 所產生的內容編碼。 回應壓縮中介軟體會使用此資訊,根據要求的 Accept-Encoding 標頭中所指定的清單來選擇提供者。

對範例應用程式發出含 Accept-Encoding: mycustomcompression 標頭的要求會傳回一個含 Content-Encoding: mycustomcompression 標頭的回應。 用戶端必須能夠解壓縮自訂的編碼,才能讓自訂壓縮實作運作。

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

使用上面的程式碼時,回應本文不會被該範例壓縮。 不過,該範例會顯示實作自訂壓縮演算法的位置。

MIME 類型

回應壓縮中介軟體會指定一組預設的 MIME 類型以進行壓縮。 請參閱支援的 MIME 類型的完整清單的原始程式碼

注意

.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

ResponseCompressionOptions.MimeTypes 來取代或附加 MIME 類型。 請注意,不支援萬用字元 MIME 類型 (例如 text/*)。 該範例應用程式為 image/svg+xml 新增了一個 MIME 類型,以及壓縮並提供 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();

新增 Vary 標頭

根據 Accept-Encoding 要求標頭壓縮回應時,回應可能會有未壓縮和多個壓縮的版本。 為了指示用戶端和 Proxy 快取存在多個版本且應該加以儲存,Vary 標頭會加上 Accept-Encoding 值。 回應中介軟體會在壓縮回應時自動新增 Vary 標頭

注意

.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

Nginx 反向 Proxy 後面的中介軟體問題

當 Nginx 代理要求時,會移除 Accept-Encoding 標頭。 移除 Accept-Encoding 標頭可防止回應壓縮中介軟體壓縮回應。 如需詳細資訊,請參閱 NGINX:壓縮和解壓縮。 此問題可透過 Figure out pass-through compression for Nginx (dotnet/aspnetcore#5989) 來追蹤。

停用 IIS 動態壓縮

若要停用在伺服器層級設定的「IIS 動態壓縮模組」,請參閱停用 IIS 模組

針對回應壓縮進行疑難排解

使用 Firefox Browser Developer 之類的工具,其允許設定Accept-Encoding要求標頭,並研究響應標頭、大小和本文。 預設情況下,回應壓縮中介軟體會壓縮符合下列條件的回應:

  • 存在 Accept-Encoding 標頭,且其值為 brgzip* 或符合自訂壓縮提供者的自訂編碼。 該值不得為 identity,也不能有設為 0 (零) 的品質值 (qvalue, q)。
  • MIME 類型 (Content-Type) 必須設定,且必須符合 ResponseCompressionOptions 上所設定的 MIME 類型。
  • 要求不得包含 Content-Range 標頭。
  • 要求必須使用不安全的通訊協定 (http) (除非在「回應壓縮中介軟體」選項中設定了安全的通訊協定 (https))。 請注意啟用安全內容壓縮時存在的上述危險

Azure 部署的範例

部署至 Azure 的範例應用程式具有下列的 Program.cs 檔案:

using Microsoft.AspNetCore.ResponseCompression;
using ResponseCompressionSample;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddResponseCompression(options =>
{
    options.EnableForHttps = true;
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
    options.Providers.Add<CustomCompressionProvider>();
    options.MimeTypes =
    ResponseCompressionDefaults.MimeTypes.Concat(
        new[] { "image/svg+xml" });
});

var app = builder.Build();

app.UseResponseCompression();

app.Map("/trickle", async (HttpResponse httpResponse) =>
{
    httpResponse.ContentType = "text/plain;charset=utf-8";

    for (int i = 0; i < 20; i++)
    {
        await httpResponse.WriteAsync("a");
        await httpResponse.Body.FlushAsync();
        await Task.Delay(TimeSpan.FromMilliseconds(50));
    }
});

app.Map("/testfile1kb.txt", () => Results.File(
    app.Environment.ContentRootFileProvider.GetFileInfo("testfile1kb.txt").PhysicalPath,
    "text/plain;charset=utf-8"));

app.Map("/banner.svg", () => Results.File(
    app.Environment.ContentRootFileProvider.GetFileInfo("banner.svg").PhysicalPath,
    "image/svg+xml;charset=utf-8"));

app.MapFallback(() => LoremIpsum.Text);

app.Run();

其他資源

注意

.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

網路頻寬是有限的資源。 減少回應的大小通常會增加應用程式的回應性,且通常會大幅提高。 減少承載大小的其中一種方法是壓縮應用程式的回應。

檢視或下載範例程式碼 \(英文\) (如何下載)

何時使用回應壓縮中介軟體

在 IIS、Apache 或 Nginx 中使用伺服器型的回應壓縮技術。 中介軟體的效能可能不符合伺服器模組的效能。 HTTP.sys 伺服器和 Kestrel 伺服器目前不提供內建的壓縮支援。

當您處於以下情況時,請使用「回應壓縮中介軟體」:

回應壓縮

通常,任何原本未壓縮的回應都可以從回應壓縮中受益。 原本未壓縮的回應通常包括:CSS、JavaScript、HTML、XML 和 JSON。 您不應壓縮原本已壓縮的資產 (例如 PNG 檔案)。 如果您嘗試進一步壓縮原本已壓縮的回應時,任何大小和傳輸時間的微小額外減少量都可能會被處理壓縮所需的時間所掩蓋。 不要壓縮小於 150-1000 個位元組的檔案 (根據檔案的內容和壓縮的效率而定)。 壓縮小型檔案的額外工作可能會產生比未壓縮檔案更大的壓縮檔。

當用戶端可以處理壓縮的內容時,用戶端必須透過隨要求傳送 Accept-Encoding 標頭來告知伺服器其能力。 當伺服器傳送壓縮內容時,它必須在 Content-Encoding 標頭中包含有關如何對壓縮回應進行編碼的資訊。 下表顯示該中介軟體所支援的內容編碼指定。

Accept-Encoding 標頭值 受中介軟體支援 描述
br 是 (預設) Brotli 壓縮資料格式
deflate No DEFLATE 壓縮資料格式
exi No W3C 高效 XML 交換
gzip Yes GZIP 檔案格式
identity Yes 「無編碼」識別碼:回應不得編碼。
pack200-gzip No JAVA 封存的網路傳輸格式
* Yes 未明確要求的任何可用內容編碼

如需詳細資訊,請參閱 IANA 官方內容編碼清單

該中介軟體可讓您為自訂 Accept-Encoding 標頭值新增額外的壓縮提供者。 如需詳細資訊,請參閱下面的自訂提供者

該中介軟體能夠在用戶端傳送品質值 (qvalue, q) 權重時對其做出反應,以設定壓縮配置的優先順序。 如需詳細資訊,請參閱 RFC 9110: Accept-Encoding

壓縮演算法需要在壓縮速度和壓縮有效性之間進行取捨。 此內容中的有效性是指壓縮後的輸出大小。 最小的大小是透過最佳壓縮來獲得的。

下表說明要求、傳送、快取和接收壓縮內容所涉及的標頭。

標題 角色
Accept-Encoding 從用戶端傳送至伺服器,以指出用戶端可接受的內容編碼配置。
Content-Encoding 從伺服器傳送至用戶端,以指出承載中的內容編碼。
Content-Length 發生壓縮時,Content-Length 標頭會被移除,因為壓縮回應時本文內容改變了。
Content-MD5 發生壓縮時,Content-MD5 標頭會被移除,因為本文內容已改變且雜湊值不再有效。
Content-Type 指定內容的 MIME 類型。 每個回應都應指定其 Content-Type。 該中介軟體會檢查此值,以判斷是否應壓縮回應。 該中介軟體會指定一組它可編碼的預設 MIME 類型,但您可以取代或新增 MIME 類型。
Vary 當伺服器以 Accept-Encoding 的值傳送至用戶端和 Proxy 時,Vary 標頭會向用戶端或 Proxy 指示它應該根據要求的 Accept-Encoding 標頭的值來快取 (改變) 回應。 使用 Vary: Accept-Encoding 標頭傳回內容的結果是,壓縮和未壓縮的回應都會被分別快取。

透過範例應用程式來探索「回應壓縮中介軟體」的功能。 該範例說明:

  • 使用 Gzip 和自訂壓縮提供者來壓縮應用程式回應。
  • 如何將 MIME 類型新增至預設的 MIME 類型清單中以進行壓縮。

組態

下列程式碼示範如何為預設 MIME 類型和壓縮提供者 (BrotliGzip) 啟用「回應壓縮中介軟體」:

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

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

注意:

  • app.UseResponseCompression 必須在任何壓縮回應的中介軟體之前呼叫。 如需詳細資訊,請參閱 ASP.NET Core 中介軟體
  • 使用 FiddlerFirefox Browser Developer 之類的工具來設定Accept-Encoding要求標頭,並研究響應標頭、大小和本文。

對範例應用程式提交不含 Accept-Encoding 標頭的要求,並觀察回應是否未壓縮。 Content-EncodingVary 標頭不會出現在回應中。

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

對範例應用程式提交含 Accept-Encoding: br 標頭的要求 (Brotli 壓縮),並觀察回應是否已壓縮。 Content-EncodingVary 標頭會出現在回應中。

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.

提供者

Brotli 壓縮提供者

使用 BrotliCompressionProvider 來以 Brotli 壓縮資料格式壓縮回應。

如果未明確將壓縮提供者新增 CompressionProviderCollection,則:

  • Brotli 壓縮提供者依預設會與 Gzip 壓縮提供者一起新增至壓縮提供者陣列中。
  • 當用戶端支援 Brotli 壓縮的資料格式時,壓縮會預設為 Brotli 壓縮。 如果用戶端不支援 Brotli,則當用戶端支援 Gzip 壓縮時,壓縮會預設為 Gzip。
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

當明確新增任何壓縮提供者時,必須新增 Brotli 壓縮提供者:

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

使用 BrotliCompressionProviderOptions 設定壓縮層級。 Brotli 壓縮提供者預設為最快的壓縮層級 (CompressionLevel.Fastest)(這可能不會產生最有效率的壓縮)。 如果想要最有效率的壓縮,請設定該中介軟體以獲得最佳的壓縮。

壓縮層級 描述
CompressionLevel.Fastest 壓縮應該盡快完成 (即使產生的輸出未以最佳方式壓縮也一樣)。
CompressionLevel.NoCompression 不應該執行壓縮。
CompressionLevel.Optimal 回應應該以最佳方式壓縮 (即使壓縮需要更多時間才能完成也一樣)。
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

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

Gzip 壓縮提供者

使用 GzipCompressionProvider 來以 Gzip 檔案格式壓縮回應。

如果未明確將壓縮提供者新增 CompressionProviderCollection,則:

  • Gzip 壓縮提供者依預設會與 Brotli 壓縮提供者一起新增至壓縮提供者陣列中。
  • 當用戶端支援 Brotli 壓縮的資料格式時,壓縮會預設為 Brotli 壓縮。 如果用戶端不支援 Brotli,則當用戶端支援 Gzip 壓縮時,壓縮會預設為 Gzip。
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
}

當明確新增任何壓縮提供者時,必須新增 Gzip 壓縮提供者:

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

使用 GzipCompressionProviderOptions 設定壓縮層級。 Gzip 壓縮提供者預設為最快的壓縮層級 (CompressionLevel.Fastest)(這可能不會產生最有效率的壓縮)。 如果想要最有效率的壓縮,請設定該中介軟體以獲得最佳的壓縮。

壓縮層級 描述
CompressionLevel.Fastest 壓縮應該盡快完成 (即使產生的輸出未以最佳方式壓縮也一樣)。
CompressionLevel.NoCompression 不應該執行壓縮。
CompressionLevel.Optimal 回應應該以最佳方式壓縮 (即使壓縮需要更多時間才能完成也一樣)。
public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();

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

自訂提供者

使用 ICompressionProvider 建立自訂壓縮實作。 EncodingName 代表這個 ICompressionProvider 所產生的內容編碼。 該中介軟體會使用此資訊,根據要求的 Accept-Encoding 標頭中所指定的清單來選擇提供者。

使用範例應用程式,用戶端提交了一個含 Accept-Encoding: mycustomcompression 標頭的要求。 該中介軟體使用了自訂壓縮實作並傳回了含 Content-Encoding: mycustomcompression 標頭的回應。 用戶端必須能夠解壓縮自訂的編碼,才能讓自訂壓縮實作運作。

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

對範例應用程式提交含 Accept-Encoding: mycustomcompression 標頭的要求,並觀察回應標頭。 VaryContent-Encoding 標頭會出現在回應中。 該範例不會壓縮回應本文 (未顯示)。 該範例的 CustomCompressionProvider 類別中沒有壓縮實作。 不過,該範例會顯示您將實作這類壓縮演算法的位置。

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 類型

該中介軟體會指定一組預設的 MIME 類型以進行壓縮:

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

以「回應壓縮中介軟體」選項取代或附加 MIME 類型。 請注意,不支援萬用字元 MIME 類型 (例如 text/*)。 該範例應用程式為 image/svg+xml 新增了一個 MIME 類型,以及壓縮並提供 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" });
    });
}

使用安全的通訊協定進行壓縮

可以使用 EnableForHttps 選項 (預設為停用) 來控制安全連線上的壓縮回應。 對動態產生的頁面使用壓縮可能可能會導致 CRIMEBREACH 攻擊之類的安全性問題。

新增 Vary 標頭

根據 Accept-Encoding 標頭壓縮回應時,回應可能有多個壓縮版本和一個未壓縮的版本。 為了指示用戶端和 Proxy 快取存在多個版本且應該加以儲存,Vary 標頭會加上 Accept-Encoding 值。 在 ASP.NET Core 2.0 或更新版本中,該中介軟體會在壓縮回應時自動新增 Vary 標頭。

Nginx 反向 Proxy 後面的中介軟體問題

當 Nginx 代理要求時,會移除 Accept-Encoding 標頭。 移除 Accept-Encoding 標頭可防止該中介軟體壓縮回應。 如需詳細資訊,請參閱 NGINX:壓縮和解壓縮。 此問題可透過 Figure out pass-through compression for Nginx (dotnet/aspnetcore#5989) 來追蹤。

使用 IIS 動態壓縮

如果您在想要為應用程式停用的伺服器層級設定使用中的 IIS 動態壓縮模組,請使用 web.config 檔案新增功能 來停用模組。 如需詳細資訊,請參閱停用 IIS 模組

疑難排解

使用 FiddlerFirefox Browser Developer 之類的工具,可讓您設定Accept-Encoding要求標頭並研究響應標頭、大小和本文。 預設情況下,回應壓縮中介軟體會壓縮符合下列條件的回應:

  • 存在 Accept-Encoding 標頭,且其值為 brgzip* 或符合您已建立的自訂壓縮提供者的自訂編碼。 該值不得為 identity,也不能有設為 0 (零) 的品質值 (qvalue, q)。
  • MIME 類型 (Content-Type) 必須設定,且必須符合 ResponseCompressionOptions 上所設定的 MIME 類型。
  • 要求不得包含 Content-Range 標頭。
  • 要求必須使用不安全的通訊協定 (http) (除非在「回應壓縮中介軟體」選項中設定了安全的通訊協定 (https))。 請注意啟用安全內容壓縮時存在的上述危險

其他資源