Сжатие ответов в ASP.NET Core

Пропускная способность сети — это ограниченный ресурс. Уменьшение размера ответа обычно увеличивает скорость реагирования приложения, часто резко. Одним из способов уменьшения размера полезных данных является сжатие ответов приложения.

Сжатие с помощью HTTPS

Сжатые ответы по защищенным подключениям можно контролировать с EnableForHttps помощью параметра, который по умолчанию отключен из-за риска безопасности. Использование сжатия с динамически созданными страницами может предоставлять приложению CRIME доступ к атакам и BREACH атакам. CRIME и BREACH атаки можно устранить в ASP.NET Core с помощью маркеров защиты от подделки. Дополнительные сведения см. на странице Предотвращение атак с использованием подделки межсайтовых запросов (XSRF/CSRF) в ASP.NET Core. Сведения об устранении рисков см. в статье об устранении BREACH рисковhttp://www.breachattack.com/

Даже если EnableForHttps приложение отключено, IIS, IIS Express и служба приложение Azure могут применять gzip на веб-сервере IIS. При просмотре заголовков ответов обратите внимание на значение сервера . Непредвиденное content-encoding значение заголовка ответа может быть результатом веб-сервера, а не конфигурацией ASP.NET Core.

Когда следует использовать ПО промежуточного слоя сжатия ответов

Используйте серверные технологии сжатия ответов в IIS, Apache или Nginx. Производительность ПО промежуточного слоя сжатия ответа, вероятно, не будет соответствовать производительности модулей сервера. HTTP.sys сервере и Kestrel сервере в настоящее время не предоставляют встроенную поддержку сжатия.

Используйте ПО промежуточного слоя сжатия ответов, если это приложение:

Сжатие ответов

Как правило, любой ответ, не сжатый в собственном коде, может воспользоваться сжатием отклика. Ответы, не сжатые в собственном коде, обычно включают CSS, JavaScript, HTML, XML и JSON. Не сжимайте собственные сжатые ресурсы, такие как PNG-файлы. При попытке дальнейшего сжатия собственно сжатого отклика любое небольшое дополнительное уменьшение размера и времени передачи, скорее всего, затмевает время обработки сжатия. Не сжимайте файлы меньше 150–1000 байт, в зависимости от содержимого файла и эффективности сжатия. Накладные расходы на сжатие небольших файлов могут создать сжатый файл больше, чем несжатый файл.

Когда клиент может обрабатывать сжатое содержимое, клиент должен сообщить серверу о своих возможностях, отправив Accept-Encoding заголовок с запросом. Когда сервер отправляет сжатое содержимое, он должен содержать сведения в заголовке Content-Encoding о кодировании сжатого ответа. Обозначения кодировки содержимого, поддерживаемые ПО промежуточного слоя сжатия ответов, показаны в следующей таблице.

Значения заголовков Accept-Encoding Поддерживаемые ПО промежуточного слоя Description
br Да (по умолчанию) Формат сжатых данных Brotli
deflate No Формат сжатых данных Deflate
exi No Эффективный обмен XML W3C
gzip Да Формат файлов gzip
identity Да Идентификатор "Нет кодирования": ответ не должен быть закодирован.
pack200-gzip No Формат сетевой передачи для архивов Java
* Да Любая доступная кодировка содержимого не запрашивается явным образом

Дополнительные сведения см. в списке кодирования официального содержимого 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 клиентов и прокси-серверов Vary заголовок указывает клиенту или прокси-серверу, что он должен кэшировать (изменять) ответы в зависимости от значения Accept-Encoding заголовка запроса. Результат возврата содержимого с Vary: Accept-Encoding заголовком заключается в том, что сжатые и несжатые ответы кэшируются отдельно.

Ознакомьтесь с функциями ПО промежуточного слоя сжатия ответов с помощью примера приложения. Пример иллюстрирует следующее:

  • Сжатие ответов приложения с помощью Gzip и пользовательских поставщиков сжатия.
  • Добавление типа MIME в список типов MIME по умолчанию для сжатия.
  • Добавление пользовательского поставщика сжатия ответов.

Настройка

В следующем коде показано, как включить ПО промежуточного слоя сжатия ответа для типов MIME по умолчанию и поставщиков сжатия (Brotli и 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();

Примечания:

Отправьте запрос в пример приложения без заголовка Accept-Encoding и обратите внимание, что ответ не сжат. Заголовок Content-Encoding не содержится в коллекции заголовков ответа.

Например, в Firefox Developer:

  • Выберите сетевую вкладку.
  • Щелкните правой кнопкой мыши запрос в списке "Сетевой запрос" и выберите "Изменить" и "Повторно отправить"
  • Переход Accept-Encoding: с gzip, deflate, br none.
  • Выберите Отправить.

Отправьте запрос в пример приложения с браузером с помощью средств разработчика и обратите внимание, что ответ сжимается. В Content-Encoding ответе присутствуют заголовки Vary .

Поставщики

Поставщики сжатия Brotli и Gzip

BrotliCompressionProvider Используйте для сжатия ответов с форматом сжатых данных Brotli.

Если поставщики сжатия явно не добавляются в :CompressionProviderCollection

  • Поставщик сжатия Brotli и поставщик сжатия Gzip добавляются по умолчанию в массив поставщиков сжатия.
  • Сжатие по умолчанию используется для сжатия Brotli, если формат сжатых данных Brotli поддерживается клиентом. Если Brotli не поддерживается клиентом, сжатие по умолчанию используется для Gzip, если клиент поддерживает сжатие Gzip.

Примечание.

По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода 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();

Задайте уровень сжатия с BrotliCompressionProviderOptions помощью и GzipCompressionProviderOptions. Поставщики сжатия 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. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Замените или добавьте типы MIME на ResponseCompressionOptions.MimeTypes. Обратите внимание, что типы MIME с подстановочными знаками, такие как text/* не поддерживаются. Пример приложения добавляет тип MIME для image/svg+xml и сжимает и служит 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запроса могут быть несжаты и несколько сжатых версий ответа. Чтобы указать клиентским и прокси-кэшам, которые существуют и должны храниться несколько версий, Vary заголовок добавляется со значением Accept-Encoding . ПО промежуточного Vary слоя ответа автоматически добавляет заголовок при сжатии ответа.

Примечание.

По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).

Проблема по промежуточного слоя при обратном прокси-сервере Nginx

При использовании запроса nginx Accept-Encoding заголовок удаляется. Удаление заголовка предотвращает сжатие отклика ПО промежуточного Accept-Encoding слоя сжатия ответа от сжатия ответа. Дополнительные сведения см. в разделе NGINX: Сжатие и декомпрессия. Эта проблема отслеживается путем определения сквозного сжатия для Nginx (dotnet/aspnetcore#5989).

Отключение динамического сжатия IIS

Чтобы отключить модуль динамического сжатия IIS, настроенный на уровне сервера, см. раздел "Отключение модулей IIS".

Устранение неполадок с сжатием ответов

Используйте средство, например Firefox Browser Developer, которое позволяет задавать Accept-Encoding заголовок запроса и изучать заголовки ответа, размер и текст. По умолчанию ПО промежуточного слоя сжатия ответа сжимает ответы, соответствующие следующим условиям:

  • Заголовок Accept-Encoding присутствует со значением br, gzip*или пользовательской кодировкой, которая соответствует пользовательскому поставщику сжатия. Значение не должно быть identity или иметь значение качества (qvalue, q) значение 0 (ноль).
  • Тип MIME (Content-Type) должен быть задан и должен соответствовать типу MIME, настроенного для него ResponseCompressionOptions.
  • Запрос не должен включать 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. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список Switch branches or tags (Переключение ветвей или тегов). Дополнительные сведения см. в статье Выбор тега версии исходного кода 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 Поддерживаемые ПО промежуточного слоя Description
br Да (по умолчанию) Формат сжатых данных Brotli
deflate No Формат сжатых данных Deflate
exi No Эффективный обмен XML W3C
gzip Да Формат файлов gzip
identity Да Идентификатор "Нет кодирования": ответ не должен быть закодирован.
pack200-gzip No Формат сетевой передачи для архивов Java
* Да Любая доступная кодировка содержимого не запрашивается явным образом

Дополнительные сведения см. в списке кодирования официального содержимого 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 клиентов и прокси-серверов Vary заголовок указывает клиенту или прокси-серверу, что он должен кэшировать (изменять) ответы в зависимости от значения Accept-Encoding заголовка запроса. Результат возврата содержимого с Vary: Accept-Encoding заголовком заключается в том, что сжатые и несжатые ответы кэшируются отдельно.

Ознакомьтесь с функциями ПО промежуточного слоя сжатия ответов с помощью примера приложения. Пример иллюстрирует следующее:

  • Сжатие ответов приложения с помощью Gzip и пользовательских поставщиков сжатия.
  • Добавление типа MIME в список типов MIME по умолчанию для сжатия.

Настройка

В следующем коде показано, как включить ПО промежуточного слоя сжатия ответа для типов MIME по умолчанию и поставщиков сжатия (Brotli и Gzip):

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

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

Примечания:

  • app.UseResponseCompression необходимо вызвать перед любым ПО промежуточного слоя, которое сжимает ответы. Дополнительные сведения см. в статье ПО промежуточного слоя ASP.NET Core.
  • Используйте средство, например Fiddler, Firefox Browser Developer, чтобы задать Accept-Encoding заголовок запроса и исследовать заголовки ответа, размер и текст.

Отправьте запрос в пример приложения без заголовка Accept-Encoding и обратите внимание, что ответ не сжат. Заголовки Content-Encoding и Vary заголовки не присутствуют в ответе.

Окно Fiddler с результатом запроса без заголовка Accept-Encoding. Ответ не сжимается.

Отправьте запрос в пример приложения с заголовком Accept-Encoding: br (сжатие Brotli) и обратите внимание, что ответ сжимается. В Content-Encoding ответе присутствуют заголовки Vary .

Окно Fiddler с результатом запроса с заголовком Accept-Encoding и значением br. В ответ добавляются заголовки

Поставщики

Поставщик сжатия 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), который может не производить наиболее эффективное сжатие. Если необходимо максимально эффективное сжатие, настройте ПО промежуточного слоя для оптимального сжатия.

Compression Level Description
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), который может не производить наиболее эффективное сжатие. Если необходимо максимально эффективное сжатие, настройте ПО промежуточного слоя для оптимального сжатия.

Compression Level Description
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 и просмотрите заголовки ответа. В Vary ответе присутствуют заголовки Content-Encoding . Текст ответа (не показан) не сжимается образцом. В классе примера отсутствует реализация CustomCompressionProvider сжатия. Однако в примере показано, где будет реализован такой алгоритм сжатия.

Окно Fiddler с результатом запроса с заголовком Accept-Encoding и значением mycustomcompression. В ответ добавляются заголовки

типы MIME

ПО промежуточного слоя задает набор типов MIME по умолчанию для сжатия:

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

Замените или добавьте типы MIME с параметрами по промежуточного слоя сжатия ответа. Обратите внимание, что типы MIME с подстановочными знаками, такие как text/* не поддерживаются. Пример приложения добавляет тип MIME для image/svg+xml и сжимает и обслуживает образ баннера 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 помощью параметра, который по умолчанию отключен. Использование сжатия с динамически созданными страницами может привести к проблемам безопасности, таким как CRIME атаки и BREACH атаки.

Добавление заголовка Vary

При сжатие ответов на Accept-Encoding основе заголовка могут быть несколько сжатых версий ответа и несжатой версии. Чтобы указать клиентским и прокси-кэшам, которые существуют и должны храниться несколько версий, Vary заголовок добавляется со значением Accept-Encoding . В ASP.NET Core 2.0 или более поздней версии ПО промежуточного слоя автоматически добавляет Vary заголовок при сжатии ответа.

Проблема по промежуточного слоя при обратном прокси-сервере Nginx

При использовании запроса nginx Accept-Encoding заголовок удаляется. Удаление заголовка предотвращает сжатие ответа ПО промежуточного Accept-Encoding слоя. Дополнительные сведения см. в разделе NGINX: Сжатие и декомпрессия. Эта проблема отслеживается путем определения сквозного сжатия для Nginx (dotnet/aspnetcore#5989).

Работа с динамическим сжатием IIS

Если у вас есть активный модуль динамического сжатия IIS, настроенный на уровне сервера, который вы хотите отключить для приложения, отключите модуль с добавлением к файлу web.config . Дополнительные сведения см. в разделе Отключение модулей IIS.

Устранение неполадок

Используйте средство, например Fiddler или Firefox Browser Developer, которое позволяет задавать Accept-Encoding заголовок запроса и изучать заголовки ответа, размер и текст. По умолчанию ПО промежуточного слоя сжатия ответа сжимает ответы, соответствующие следующим условиям:

  • Заголовок Accept-Encoding присутствует со значением br, gzip*или пользовательской кодировкой, которая соответствует установленному поставщику пользовательского сжатия. Значение не должно быть identity или иметь значение качества (qvalue, q) значение 0 (ноль).
  • Тип MIME (Content-Type) должен быть задан и должен соответствовать типу MIME, настроенного для него ResponseCompressionOptions.
  • Запрос не должен включать Content-Range заголовок.
  • Запрос должен использовать небезопасный протокол (http), если в параметрах промежуточного слоя сжатия ответа не настроен безопасный протокол (https). Обратите внимание на опасность , описанную выше при включении безопасного сжатия содержимого.

Дополнительные ресурсы