Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Пропускная способность сети — это ограниченный ресурс. Уменьшение размера ответа обычно увеличивает скорость реагирования приложения, часто резко. Одним из способов уменьшения размера полезных данных является сжатие ответов из приложения. В этой статье описывается, как реализовать сжатие ответов на ваших приложениях посредством посреднического программного обеспечения сжатия ответов в ASP.NET Core.
Изучение сжатия с помощью HTTPS
Сжатые ответы по защищенным подключениям можно контролировать с помощью параметра EnableForHttps, который по умолчанию отключен из-за риска безопасности. Использование сжатия с динамически генерируемыми страницами может подвергать приложение атакам CRIME и BREACH. CRIME и BREACH атаки можно устранить в ASP.NET Core с помощью маркеров защиты от подделки. Дополнительные сведения см. на странице Предотвращение атак с использованием подделки межсайтовых запросов (XSRF/CSRF) в ASP.NET Core. Сведения о методах снижения риска атак см. в разделе Меры по снижению риска на http://www.breachattack.com/.
Даже если приложение отключает свойство EnableForHttps (false), Internet Information Services (IIS), IIS Express и Служба приложений Azure может применять Gzip на веб-сервере IIS. При просмотре заголовков ответов запишите значение заголовка Сервера. Непредвиденное значение заголовка ответа content-encoding может быть результатом веб-сервера, а не конфигурацией приложения ASP.NET Core.
Определение, когда использовать Middleware для сжатия ответов
Используйте серверные технологии сжатия ответов в IIS, Apache или Nginx. Производительность ПО промежуточного слоя сжатия ответа, вероятно, не может соответствовать производительности модулей сервера. Сервер HTTP.sys и Kestrel сервер в настоящее время не предлагают встроенную поддержку сжатия.
Используйте промежуточное программное обеспечение для сжатия ответов, если приложение:
Не удается использовать следующие серверные технологии сжатия:
Размещение непосредственно на:
Изучение сжатия ответов
Как правило, любой ответ, не являющийся изначально сжатым, может выиграть от сжатия ответа. Ответы, не сжатые в собственном коде, обычно включают CSS, JavaScript, HTML, XML и JSON. Не сжимайте собственные сжатые ресурсы, такие как PNG-файлы. При попытке дальнейшего сжатия исходно сжатого отклика небольшое дополнительное уменьшение объема и времени передачи, скорее всего, будет компенсировано временем, необходимым на обработку сжатия. Не сжимайте файлы меньше 150 – 1000 байт, в зависимости от содержимого файла и эффективности сжатия. Затраты на сжатие небольших файлов могут привести к тому, что сжатый файл больше, чем несжатый файл.
Когда клиент может обрабатывать сжатый контент, клиент должен сообщить серверу о своих возможностях, отправив заголовок Accept-Encoding с запросом. Когда сервер отправляет сжатое содержимое, он должен содержать сведения в заголовке "Кодирование содержимого " относительно кодирования сжатого ответа.
В следующей таблице показаны обозначения форматов кодировки содержимого для заголовка Accept-Encoding и указано, поддерживается ли это обозначение промежуточным программным обеспечением сжатия ответов.
| Назначение | Middleware | Формат | Сведения |
|---|---|---|---|
br |
Да (по умолчанию) | Формат сжатых данных Brotli | RFC 7932 |
deflate |
No | Формат данных, сжатых методом DEFLATE | RFC 1951 |
exi |
No | Эффективный обмен XML (EXI) | Рекомендация W3C |
gzip |
Yes | Формат файла Gzip | RFC 1952 |
identity |
Yes | "Без кодирования" — ответ не должен быть закодирован | Устранение неполадок с сжатием ответов |
pack200-gzip |
No | Формат передачи сети для архивов Java | JSR 200 |
* (звездочка) |
Yes | "Подстановочный знак" — любая доступная кодировка содержимого не запрашивается явно | Устранение неполадок с сжатием ответов |
Дополнительные сведения см. в списке кодирования официального содержимого IANA для параметров HTTP.
Промежуточный слой сжатия ответа позволяет добавлять других поставщиков сжатия для пользовательских Accept-Encoding значений заголовков. Для получения дополнительной информации см. Custom Providers далее в этой статье.
Промежуточное ПО для сжатия ответа может реагировать на значение качества (qvalue, q) и его вес при отправке клиентом для приоритезации схем сжатия. Дополнительные сведения см. в статье RFC 9110: семантика HTTP (раздел 12.5.3 Accept-Encoding).
Алгоритмы сжатия подвергаются компромиссу между скоростью сжатия и эффективностью сжатия. Эффективность в этом контексте относится к размеру выходных данных после сжатия. Наименьший размер достигается оптимальным сжатием.
Заголовки, участвующие в запросе, отправке, кэшировании и получении сжатого содержимого, описаны в следующей таблице.
| Header | Role | Сведения |
|---|---|---|
Accept-Encoding |
Отправляется от клиента на сервер, чтобы указать схемы кодирования содержимого, приемлемые для клиента. | заголовок Accept-Encoding |
Content-Encoding |
Отправляется с сервера на клиент, чтобы указать кодировку содержимого в теле сообщения. | Заголовок кодирования содержимого |
Content-Length |
При сжатии заголовок Content-Length удаляется, так как содержимое тела изменяется при сжатии ответа. |
Заголовок Content-Length |
Content-MD5 |
При сжатии заголовок Content-MD5 удаляется, поскольку содержимое тела изменяется и хэш становится недействительным. |
RFC 1864: поле заголовка Content-MD5 |
Content-Type |
Указывает тип MIME содержимого. Каждый ответ должен указывать его Content-Type значение. ПО промежуточного слоя сжатия ответа проверяет это значение, чтобы определить, следует ли сжать ответ. ПО промежуточного слоя сжатия ответа указывает набор типов MIME по умолчанию , которые он может кодировать, и их можно заменить или добавить. |
Заголовок Content-Type |
Vary |
При отправке сервером значения Accept-Encoding клиентам и прокси-серверам, заголовок Vary указывает клиенту или прокси-серверу, что он должен кэшировать (варьировать) ответы в зависимости от значения заголовка Accept-Encoding в запросе. Результат возврата содержимого с Vary: Accept-Encoding заголовком заключается в том, что сжатые и несжатые ответы кэшируются отдельно. |
Различаемый заголовок |
Изучите функции промежуточного ПО для сжатия ответов с использованием примера приложения. Пример иллюстрирует следующее:
- Сжатие ответов приложения с помощью Gzip и кастомных поставщиков сжатия.
- Как добавить тип MIME в список типов MIME по умолчанию для сжатия.
- Как добавить настраиваемого поставщика сжатия ответов.
Настройка middleware для сжатия ответов
В следующем коде показано, как включить ПО промежуточного слоя сжатия ответа для типов 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();
Заметки о промежуточном программном обеспечении для сжатия ответов
При работе с промежуточным ПО для сжатия ответов учтите следующие моменты:
-
EnableForHttpsЗадание свойстваtrueпредставляет угрозу безопасности. Дополнительные сведения см. в разделе "Сжатие с использованием HTTPS " ранее в этой статье. - Метод app.UseResponseCompression должен вызываться перед любым промежуточным ПО, которое сжимает ответы. Дополнительные сведения см. в разделе ASP.NET Core ПО промежуточного слоя > порядок выполнения.
- Используйте средство, например Firefox Browser — Developer Edition , чтобы задать
Accept-Encodingзаголовок запроса и проверить заголовки ответа, размер и текст ответа.
Отправьте запрос в пример приложения без заголовка Accept-Encoding и обратите внимание, что ответ не сжат. Заголовок Content-Encoding не содержится в коллекции заголовков ответа.
Например, в Firefox Developer:
- Выберите сетевую вкладку.
- Щелкните правой кнопкой мыши запрос в списке сетевых запросов и выберите "Изменить" и повторно отправить его.
- Измените значение параметра
Accept-Encoding:сgzip, deflate, brнаnone. - Нажмите кнопку "Отправить".
Отправьте запрос в пример приложения с браузером с помощью средств разработчика и обратите внимание, что ответ сжимается. На ответе присутствуют заголовки Content-Encoding и Vary.
Проверка поставщиков
В этом разделе содержатся сведения о поставщиках сжатия, включая Brotli, Gzip и пользовательских поставщиков.
Поставщики сжатия Brotli и Gzip
Используйте класс BrotliCompressionProvider для сжатия ответов в формате сжатых данных Brotli согласно RFC 7932.
Если поставщики сжатия явно не добавляются в CompressionProviderCollection класс:
- По умолчанию поставщики сжатия Brotli и Gzip добавляются в массив поставщиков сжатия.
- Когда клиент поддерживает формат сжатых данных Brotli, по умолчанию используется сжатие Brotli.
- Если клиент не поддерживает Brotli, сжатие по умолчанию используется для Gzip, если клиент поддерживает сжатие Gzip.
При добавлении поставщика сжатия другие поставщики не добавляются. Например, если поставщик сжатия Gzip является единственным явно добавленным, другие поставщики сжатия не будут добавлены.
Note
По ссылкам в документации на справочные материалы по .NET обычно загружается основная ветвь репозитория, которая представляет направление текущей разработки, предназначенное для следующего релиза .NET. Чтобы выбрать тег для конкретного выпуска, используйте раскрывающееся меню Переключение ветвей или тегов. Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Следующий код:
- Включает сжатие ответов для 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.
Note
В документации ссылки на справочные материалы по .NET обычно ведут на основную ветвь репозитория, которая представляет текущую разработку для следующего выпуска .NET. Чтобы выбрать тег для определенного выпуска, используйте раскрывающийся список «Переключение ветвей или тегов». Дополнительные сведения см. в статье Выбор тега версии исходного кода 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" в файл ResponseCompressionBody.cs автоматически при сжатии ответа.
Note
По ссылкам в документации на справочные материалы по .NET обычно загружается ветвь репозитория по умолчанию, отражающая текущую разработку следующей версии .NET. Чтобы выбрать тег для конкретного выпуска, используйте раскрывающийся список Переключение веток или тегов. Дополнительные сведения см. в статье Выбор тега версии исходного кода ASP.NET Core (dotnet/AspNetCore.Docs #26205).
Проблемы с обратным прокси-сервером Nginx
Когда Nginx проксирует запрос, заголовок Accept-Encoding удаляется. Удаление заголовка Accept-Encoding предотвращает промежуточное ПО сжатия от обработки и сжатия ответа. Дополнительные сведения см. в разделе Nginx: Сжатие и декомпрессия. Эта проблема отслеживается в GitHub в задаче dotnet/aspnetcore #5989 - Разработать сквозное сжатие для Nginx.
Отключение динамического сжатия IIS
Чтобы отключить модуль динамического сжатия IIS, настроенный на уровне сервера, см. раздел "Отключение модулей IIS".
Устранение неполадок с сжатием ответов
Используйте средство, например Firefox Browser — версия для разработчиков, которое позволяет задать Accept-Encoding заголовок запроса и изучать заголовки ответов, размер и содержимое. По умолчанию промежуточный слой программы для сжатия ответов сжимает ответы, соответствующие следующим условиям:
Заголовок
Accept-Encodingприсутствует со значениемbr,gzip,*(звездочка) или пользовательской кодировкой, которая соответствует индивидуальному поставщику сжатия. Значение не должно бытьidentity(без кодировки) или иметь значение качества (qvalue,q) значение 0 (ноль).Тип MIME (
Content-Type) должен быть задан и должен соответствовать типу MIME, настроенного ResponseCompressionOptions в классе.Запрос не должен включать заголовок Content-Range.
Запрос должен использовать небезопасный протокол гипертекста (http), если в параметрах промежуточного слоя сжатия ответа не настроен безопасный протокол гипертекста (https).
Important
Ознакомьтесь с рисками, связанными с включением безопасного сжатия содержимого, как описано в разделе "Сжатие с помощью 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();
Связанный контент
Пропускная способность сети — это ограниченный ресурс. Уменьшение размера ответа обычно увеличивает скорость реагирования приложения, часто резко. Одним из способов уменьшения размера полезных данных является сжатие ответов приложения.
Просмотреть или скачать образец кода (описание загрузки)
Когда следует использовать ПО промежуточного слоя сжатия ответов
Используйте серверные технологии сжатия ответов в IIS, Apache или Nginx. Производительность промежуточного слоя, возможно, не будет такой же, как у модулей сервера. сервер HTTP.sys и Kestrel сервер в настоящее время не предоставляют встроенную поддержку сжатия.
Используйте промежуточное программное обеспечение для сжатия ответов, когда вы:
- Не удается использовать следующие серверные технологии сжатия:
- Размещение непосредственно на:
- HTTP.sys сервер (ранее называемый WebListener)
- 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 |
Yes | Формат файлов gzip |
identity |
Yes | Идентификатор "Нет кодирования": ответ не должен быть закодирован. |
pack200-gzip |
No | Формат сетевой передачи для архивов Java |
* |
Yes | Любая доступная кодировка содержимого не запрашивается явным образом |
Дополнительные сведения см. в Официальном списке кодов содержимого IANA.
ПО промежуточного слоя позволяет добавлять дополнительные поставщики сжатия для пользовательских Accept-Encoding значений заголовков. Дополнительные сведения см. в разделе ниже «Настраиваемые поставщики».
ПО промежуточного слоя может реагировать на значение качества (qvalue q) веса при отправке клиентом для определения приоритетов методов сжатия. Дополнительные сведения см. в статье RFC 9110: Accept-Encoding.
Алгоритмы сжатия подвергаются компромиссу между скоростью сжатия и эффективностью сжатия. Эффективность в этом контексте относится к размеру выходных данных после сжатия. Наименьший размер достигается наиболее оптимальным сжатием.
Заголовки, связанные с запросом, отправкой, кэшированием и получением сжатого содержимого, описаны в таблице ниже.
| Header | Role |
|---|---|
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 по умолчанию для сжатия.
Configuration
В следующем коде показано, как включить ПО промежуточного слоя сжатия ответа для типов MIME по умолчанию и поставщиков сжатия (Brotli и Gzip):
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseResponseCompression();
}
}
Notes:
-
app.UseResponseCompressionнеобходимо вызвать перед любым промежуточным ПО, сжимающим ответы. Дополнительные сведения см. в статье ПО промежуточного слоя ASP.NET Core. - Используйте средство, например Fiddler, Firefox Browser Developer, чтобы задать заголовок
Accept-Encodingзапроса и изучить заголовки ответа, их размеры и содержимое.
Отправьте запрос в пример приложения без заголовка Accept-Encoding и обратите внимание, что ответ не сжат. Заголовки Content-Encoding и Vary отсутствуют в ответе.
Отправьте запрос в пример приложения с заголовком Accept-Encoding: br (сжатие Brotli) и обратите внимание, что ответ сжимается. Заголовки Content-Encoding и Vary присутствуют в ответе.
Providers
Поставщик сжатия 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), который может не производить наиболее эффективное сжатие. Если необходимо максимально эффективное сжатие, настройте ПО промежуточного слоя для оптимального сжатия.
| Уровень сжатия | 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), который может не производить наиболее эффективное сжатие. Если необходимо максимально эффективное сжатие, настройте ПО промежуточного слоя для оптимального сжатия.
| Уровень сжатия | 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. Однако в примере показано, где будет реализован такой алгоритм сжатия.
Типы MIME
ПО промежуточного слоя задает набор типов MIME по умолчанию для сжатия:
application/javascriptapplication/jsonapplication/xmltext/csstext/htmltext/jsontext/plaintext/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.
Troubleshooting
Используйте средство, например Fiddler или Firefox Browser Developer, которое позволяет задавать Accept-Encoding заголовок запроса и изучать заголовки ответа, размер и текст. Программное обеспечение промежуточного слоя для сжатия ответов по умолчанию сжимает ответы, удовлетворяющие следующим условиям:
- Заголовок
Accept-Encodingприсутствует со значениемbr,gzip,*или пользовательской кодировкой, которая соответствует вашему настроенному провайдеру пользовательского сжатия. Значение не должно бытьidentityили иметь значение качества (qvalue,q) значение 0 (ноль). - Тип MIME (
Content-Type) должен быть задан и должен соответствовать типу MIME, настроенному на ResponseCompressionOptions. - Запрос не должен включать
Content-Rangeзаголовок. - Запрос должен использовать небезопасный протокол (http), если в параметрах промежуточного слоя сжатия ответа не настроен безопасный протокол (https). Обратите внимание на опасность , описанную выше при включении безопасного сжатия содержимого.
Дополнительные ресурсы
ASP.NET Core