- ASP.NET Core 中的响应压缩Response compression in ASP.NET Core
- 何时使用响应压缩中间件When to use Response Compression Middleware
- 响应压缩Response compression
- 程序包Package
- 配置Configuration
- 提供程序Providers
- MIME 类型MIME types
- 安全协议压缩Compression with secure protocol
- 添加 Vary 标头Adding the Vary header
- Nginx 反向代理后的中间件问题Middleware issue when behind an Nginx reverse proxy
- 使用 IIS 动态压缩Working with IIS dynamic compression
- 故障排除Troubleshooting
- 其他资源Additional resources
- 何时使用响应压缩中间件When to use Response Compression Middleware
- 响应压缩Response compression
- 程序包Package
- 配置Configuration
- 提供程序Providers
- MIME 类型MIME types
- 安全协议压缩Compression with secure protocol
- 添加 Vary 标头Adding the Vary header
- Nginx 反向代理后的中间件问题Middleware issue when behind an Nginx reverse proxy
- 使用 IIS 动态压缩Working with IIS dynamic compression
- 故障排除Troubleshooting
- 其他资源Additional resources
- 何时使用响应压缩中间件When to use Response Compression Middleware
- 响应压缩Response compression
- 程序包Package
- 配置Configuration
- 提供程序Providers
- MIME 类型MIME types
- 安全协议压缩Compression with secure protocol
- 添加 Vary 标头Adding the Vary header
- Nginx 反向代理后的中间件问题Middleware issue when behind an Nginx reverse proxy
- 使用 IIS 动态压缩Working with IIS dynamic compression
- 故障排除Troubleshooting
- 其他资源Additional resources
ASP.NET Core 中的响应压缩Response compression in ASP.NET Core
本文内容
网络带宽是一种有限的资源。减小响应大小通常会显著提高应用程序的响应能力。减少负载大小的一种方法是压缩应用的响应。
何时使用响应压缩中间件When to use Response Compression Middleware
在 IIS、Apache 或 Nginx 中使用基于服务器的响应压缩技术。中间件的性能与服务器模块的性能可能不一致。Http.sys 服务器服务器和Kestrel服务器当前不提供内置的压缩支持。
使用响应压缩中间件:
- 无法使用以下基于服务器的压缩技术:
- 直接在上托管:
- Http.sys 服务器(以前称为 WebListener)
- Kestrel 服务器
响应压缩Response compression
通常,任何未进行本机压缩的响应都可以从响应压缩中获益。不以本机方式压缩的响应通常包括: CSS、JavaScript、HTML、XML 和 JSON。不应压缩本机压缩的资产,例如 PNG 文件。如果尝试进一步压缩本机压缩的响应,则可能会相形见绌处理压缩所需的时间,从而减少大小和传输时间的任何小部分。不要压缩小于大约150-1000 字节的文件(具体取决于文件的内容和压缩的效率)。压缩小文件的开销可能会产生比未压缩文件更大的压缩文件。
如果客户端可以处理压缩的内容,则客户端必须通过请求发送 Accept-Encoding
标头来通知服务器的功能。当服务器发送压缩内容时,它必须在 Content-Encoding
标头中包括有关如何对压缩的响应进行编码的信息。下表显示了中间件支持的内容编码称号。
Accept-Encoding 标头值 | 支持的中间件 | 说明 |
---|---|---|
br | 是(默认值) | Brotli 压缩数据格式 |
deflate | 否 | DEFLATE 压缩数据格式 |
exi | 否 | W3C 高效 XML 交换 |
gzip | 是 | Gzip 文件格式 |
identity | 是 | "无编码" 标识符:不能对响应进行编码。 |
pack200-gzip | 否 | Java 存档的网络传输格式 |
* | 是 | 未显式请求任何可用内容编码 |
有关详细信息,请参阅IANA 官方内容编码列表。
中间件允许您为自定义 Accept-Encoding
标头值添加更多压缩提供程序。有关详细信息,请参阅下面的自定义提供程序。
当客户端发送时,中间件能够对质量值(qvalue、q
)加权作出反应,以确定压缩方案的优先级。有关详细信息,请参阅RFC 7231:接受编码。
压缩算法会在压缩速度与压缩效率之间进行权衡。此上下文的有效性是指压缩后的输出大小。最小大小是通过最佳压缩来实现的。
下表介绍了请求、发送、缓存和接收压缩内容所涉及的标头。
标头 | 角色 |
---|---|
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 类型的默认列表以进行压缩。
程序包Package
响应压缩中间件由AspNetCore. ResponseCompression包提供,后者隐式包含在 ASP.NET Core 应用中。
配置Configuration
下面的代码演示如何为默认 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、 Firebug或Postman等工具设置
Accept-Encoding
请求标头,并研究响应标头、大小和正文。
将请求提交到没有 Accept-Encoding
标头的示例应用,并观察响应是否未压缩。响应中不存在 Content-Encoding
和 Vary
标头。
将请求提交到带有 Accept-Encoding: br
标头的示例应用(Brotli 压缩),并观察响应是否已压缩。响应中存在 Content-Encoding
和 Vary
标头。
提供程序Providers
Brotli 压缩提供程序Brotli Compression Provider
使用 BrotliCompressionProvider 压缩Brotli 压缩数据格式的响应。
如果未将压缩提供程序显式添加到 CompressionProviderCollection:
- 默认情况下,Brotli 压缩提供程序会随Gzip 压缩提供程序一起添加到压缩提供程序的数组中。
- 当客户端支持 Brotli 压缩数据格式时,压缩默认为 Brotli 压缩。如果客户端不支持 Brotli,则在客户端支持 Gzip 压缩时,压缩默认为 Gzip。
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
}
在显式添加任何压缩提供程序时,必须添加 Brotoli 压缩提供程序:
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),这可能不会生成最有效的压缩。如果需要最有效的压缩,请将中间件配置为最佳压缩。
Compression Level | 说明 |
---|---|
CompressionLevel | 压缩应该尽快完成,即使生成的输出未以最佳方式压缩。 |
CompressionLevel. NoCompression | 不应执行压缩。 |
CompressionLevel | 即使压缩需要更长的时间,也应以最佳方式压缩响应。 |
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.Configure<BrotliCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.Fastest;
});
}
Gzip 压缩提供程序Gzip Compression Provider
使用 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),这可能不会生成最有效的压缩。如果需要最有效的压缩,请将中间件配置为最佳压缩。
Compression Level | 说明 |
---|---|
CompressionLevel | 压缩应该尽快完成,即使生成的输出未以最佳方式压缩。 |
CompressionLevel. NoCompression | 不应执行压缩。 |
CompressionLevel | 即使压缩需要更长的时间,也应以最佳方式压缩响应。 |
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.Configure<GzipCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.Fastest;
});
}
自定义提供程序Custom providers
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 types
中间件为压缩指定了一组默认的 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 横幅图像(横幅)进行压缩和服务。
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" });
});
}
安全协议压缩Compression with secure protocol
可以使用默认情况下禁用 EnableForHttps
选项控制安全连接上的压缩响应。在动态生成的页面中使用压缩可能会导致安全问题,例如犯罪)和漏洞)攻击。
添加 Vary 标头Adding the Vary header
根据 Accept-Encoding
标头压缩响应时,可能会有多个压缩版本的响应和未压缩的版本。为了指示客户端和代理缓存有多个版本存在且应该存储,将使用 Accept-Encoding
的值添加 Vary
标头。在 ASP.NET Core 2.0 或更高版本中,在对响应进行压缩时,中间件会自动添加 Vary
标头。
Nginx 反向代理后的中间件问题Middleware issue when behind an Nginx reverse proxy
当 Nginx 代理请求时,将删除 Accept-Encoding
标头。删除 Accept-Encoding
标头会阻止中间件压缩响应。有关详细信息,请参阅NGINX:压缩和解压缩。此问题通过Nginx 的传递压缩(aspnet/BasicMiddleware #123)进行跟踪。
使用 IIS 动态压缩Working with IIS dynamic compression
如果在要为应用禁用的服务器级别上配置了活动的 IIS 动态压缩模块,请使用web.config文件的附加功能禁用该模块。有关详细信息,请参阅禁用 IIS 模块。
故障排除Troubleshooting
使用Fiddler、 Firebug或Postman之类的工具,通过该工具,可以设置 Accept-Encoding
请求标头并研究响应标头、大小和正文。默认情况下,响应压缩中间件会压缩满足以下条件的响应:
Accept-Encoding
标头存在,其值为br
、gzip
、*
或自定义编码,此值与已建立的自定义压缩提供程序匹配。该值不能为identity
,或者其质量值(qvalue,q
)设置为0(零)。- 必须设置 MIME 类型(
Content-Type
),并且该类型必须与 ResponseCompressionOptions上配置的 MIME 类型匹配。 - 请求不能包含
Content-Range
标头。 - 除非在响应压缩中间件选项中配置了安全协议(https),否则请求必须使用不安全的协议(http)。启用安全内容压缩时,请注意上面所述的危险。
其他资源Additional resources
- ASP.NET Core 中的应用启动
- ASP.NET Core 中间件
- Mozilla 开发人员网络:接受编码
- RFC 7231 部分3.1.2.1: Content Codings
- RFC 7230 部分4.2.3: Gzip 编码
- GZIP 文件格式规范版本4。3
网络带宽是一种有限的资源。减小响应大小通常会显著提高应用程序的响应能力。减少负载大小的一种方法是压缩应用的响应。
何时使用响应压缩中间件When to use Response Compression Middleware
在 IIS、Apache 或 Nginx 中使用基于服务器的响应压缩技术。中间件的性能与服务器模块的性能可能不一致。Http.sys 服务器服务器和Kestrel服务器当前不提供内置的压缩支持。
使用响应压缩中间件:
- 无法使用以下基于服务器的压缩技术:
- 直接在上托管:
- Http.sys 服务器(以前称为 WebListener)
- Kestrel 服务器
响应压缩Response compression
通常,任何未进行本机压缩的响应都可以从响应压缩中获益。不以本机方式压缩的响应通常包括: CSS、JavaScript、HTML、XML 和 JSON。不应压缩本机压缩的资产,例如 PNG 文件。如果尝试进一步压缩本机压缩的响应,则可能会相形见绌处理压缩所需的时间,从而减少大小和传输时间的任何小部分。不要压缩小于大约150-1000 字节的文件(具体取决于文件的内容和压缩的效率)。压缩小文件的开销可能会产生比未压缩文件更大的压缩文件。
如果客户端可以处理压缩的内容,则客户端必须通过请求发送 Accept-Encoding
标头来通知服务器的功能。当服务器发送压缩内容时,它必须在 Content-Encoding
标头中包括有关如何对压缩的响应进行编码的信息。下表显示了中间件支持的内容编码称号。
Accept-Encoding 标头值 | 支持的中间件 | 说明 |
---|---|---|
br | 是(默认值) | Brotli 压缩数据格式 |
deflate | 否 | DEFLATE 压缩数据格式 |
exi | 否 | W3C 高效 XML 交换 |
gzip | 是 | Gzip 文件格式 |
identity | 是 | "无编码" 标识符:不能对响应进行编码。 |
pack200-gzip | 否 | Java 存档的网络传输格式 |
* | 是 | 未显式请求任何可用内容编码 |
有关详细信息,请参阅IANA 官方内容编码列表。
中间件允许您为自定义 Accept-Encoding
标头值添加更多压缩提供程序。有关详细信息,请参阅下面的自定义提供程序。
当客户端发送时,中间件能够对质量值(qvalue、q
)加权作出反应,以确定压缩方案的优先级。有关详细信息,请参阅RFC 7231:接受编码。
压缩算法会在压缩速度与压缩效率之间进行权衡。此上下文的有效性是指压缩后的输出大小。最小大小是通过最佳压缩来实现的。
下表介绍了请求、发送、缓存和接收压缩内容所涉及的标头。
标头 | 角色 |
---|---|
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 类型的默认列表以进行压缩。
程序包Package
若要将中间件包含在项目中,请添加对AspNetCore 元包的引用,其中包括AspNetCore. ResponseCompression包。
配置Configuration
下面的代码演示如何为默认 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、 Firebug或Postman等工具设置
Accept-Encoding
请求标头,并研究响应标头、大小和正文。
将请求提交到没有 Accept-Encoding
标头的示例应用,并观察响应是否未压缩。响应中不存在 Content-Encoding
和 Vary
标头。
将请求提交到带有 Accept-Encoding: br
标头的示例应用(Brotli 压缩),并观察响应是否已压缩。响应中存在 Content-Encoding
和 Vary
标头。
提供程序Providers
Brotli 压缩提供程序Brotli Compression Provider
使用 BrotliCompressionProvider 压缩Brotli 压缩数据格式的响应。
如果未将压缩提供程序显式添加到 CompressionProviderCollection:
- 默认情况下,Brotli 压缩提供程序会随Gzip 压缩提供程序一起添加到压缩提供程序的数组中。
- 当客户端支持 Brotli 压缩数据格式时,压缩默认为 Brotli 压缩。如果客户端不支持 Brotli,则在客户端支持 Gzip 压缩时,压缩默认为 Gzip。
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
}
在显式添加任何压缩提供程序时,必须添加 Brotoli 压缩提供程序:
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),这可能不会生成最有效的压缩。如果需要最有效的压缩,请将中间件配置为最佳压缩。
Compression Level | 说明 |
---|---|
CompressionLevel | 压缩应该尽快完成,即使生成的输出未以最佳方式压缩。 |
CompressionLevel. NoCompression | 不应执行压缩。 |
CompressionLevel | 即使压缩需要更长的时间,也应以最佳方式压缩响应。 |
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.Configure<BrotliCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.Fastest;
});
}
Gzip 压缩提供程序Gzip Compression Provider
使用 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),这可能不会生成最有效的压缩。如果需要最有效的压缩,请将中间件配置为最佳压缩。
Compression Level | 说明 |
---|---|
CompressionLevel | 压缩应该尽快完成,即使生成的输出未以最佳方式压缩。 |
CompressionLevel. NoCompression | 不应执行压缩。 |
CompressionLevel | 即使压缩需要更长的时间,也应以最佳方式压缩响应。 |
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.Configure<GzipCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.Fastest;
});
}
自定义提供程序Custom providers
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 types
中间件为压缩指定了一组默认的 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 横幅图像(横幅)进行压缩和服务。
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" });
});
}
安全协议压缩Compression with secure protocol
可以使用默认情况下禁用 EnableForHttps
选项控制安全连接上的压缩响应。在动态生成的页面中使用压缩可能会导致安全问题,例如犯罪)和漏洞)攻击。
添加 Vary 标头Adding the Vary header
根据 Accept-Encoding
标头压缩响应时,可能会有多个压缩版本的响应和未压缩的版本。为了指示客户端和代理缓存有多个版本存在且应该存储,将使用 Accept-Encoding
的值添加 Vary
标头。在 ASP.NET Core 2.0 或更高版本中,在对响应进行压缩时,中间件会自动添加 Vary
标头。
Nginx 反向代理后的中间件问题Middleware issue when behind an Nginx reverse proxy
当 Nginx 代理请求时,将删除 Accept-Encoding
标头。删除 Accept-Encoding
标头会阻止中间件压缩响应。有关详细信息,请参阅NGINX:压缩和解压缩。此问题通过Nginx 的传递压缩(aspnet/BasicMiddleware #123)进行跟踪。
使用 IIS 动态压缩Working with IIS dynamic compression
如果在要为应用禁用的服务器级别上配置了活动的 IIS 动态压缩模块,请使用web.config文件的附加功能禁用该模块。有关详细信息,请参阅禁用 IIS 模块。
故障排除Troubleshooting
使用Fiddler、 Firebug或Postman之类的工具,通过该工具,可以设置 Accept-Encoding
请求标头并研究响应标头、大小和正文。默认情况下,响应压缩中间件会压缩满足以下条件的响应:
Accept-Encoding
标头存在,其值为br
、gzip
、*
或自定义编码,此值与已建立的自定义压缩提供程序匹配。该值不能为identity
,或者其质量值(qvalue,q
)设置为0(零)。- 必须设置 MIME 类型(
Content-Type
),并且该类型必须与 ResponseCompressionOptions上配置的 MIME 类型匹配。 - 请求不能包含
Content-Range
标头。 - 除非在响应压缩中间件选项中配置了安全协议(https),否则请求必须使用不安全的协议(http)。启用安全内容压缩时,请注意上面所述的危险。
其他资源Additional resources
- ASP.NET Core 中的应用启动
- ASP.NET Core 中间件
- Mozilla 开发人员网络:接受编码
- RFC 7231 部分3.1.2.1: Content Codings
- RFC 7230 部分4.2.3: Gzip 编码
- GZIP 文件格式规范版本4。3
网络带宽是一种有限的资源。减小响应大小通常会显著提高应用程序的响应能力。减少负载大小的一种方法是压缩应用的响应。
何时使用响应压缩中间件When to use Response Compression Middleware
在 IIS、Apache 或 Nginx 中使用基于服务器的响应压缩技术。中间件的性能与服务器模块的性能可能不一致。Http.sys 服务器服务器和Kestrel服务器当前不提供内置的压缩支持。
使用响应压缩中间件:
- 无法使用以下基于服务器的压缩技术:
- 直接在上托管:
- Http.sys 服务器(以前称为 WebListener)
- Kestrel 服务器
响应压缩Response compression
通常,任何未进行本机压缩的响应都可以从响应压缩中获益。不以本机方式压缩的响应通常包括: CSS、JavaScript、HTML、XML 和 JSON。不应压缩本机压缩的资产,例如 PNG 文件。如果尝试进一步压缩本机压缩的响应,则可能会相形见绌处理压缩所需的时间,从而减少大小和传输时间的任何小部分。不要压缩小于大约150-1000 字节的文件(具体取决于文件的内容和压缩的效率)。压缩小文件的开销可能会产生比未压缩文件更大的压缩文件。
如果客户端可以处理压缩的内容,则客户端必须通过请求发送 Accept-Encoding
标头来通知服务器的功能。当服务器发送压缩内容时,它必须在 Content-Encoding
标头中包括有关如何对压缩的响应进行编码的信息。下表显示了中间件支持的内容编码称号。
Accept-Encoding 标头值 | 支持的中间件 | 说明 |
---|---|---|
br | 否 | Brotli 压缩数据格式 |
deflate | 否 | DEFLATE 压缩数据格式 |
exi | 否 | W3C 高效 XML 交换 |
gzip | 是(默认值) | Gzip 文件格式 |
identity | 是 | "无编码" 标识符:不能对响应进行编码。 |
pack200-gzip | 否 | Java 存档的网络传输格式 |
* | 是 | 未显式请求任何可用内容编码 |
有关详细信息,请参阅IANA 官方内容编码列表。
中间件允许您为自定义 Accept-Encoding
标头值添加更多压缩提供程序。有关详细信息,请参阅下面的自定义提供程序。
当客户端发送时,中间件能够对质量值(qvalue、q
)加权作出反应,以确定压缩方案的优先级。有关详细信息,请参阅RFC 7231:接受编码。
压缩算法会在压缩速度与压缩效率之间进行权衡。此上下文的有效性是指压缩后的输出大小。最小大小是通过最佳压缩来实现的。
下表介绍了请求、发送、缓存和接收压缩内容所涉及的标头。
标头 | 角色 |
---|---|
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 类型的默认列表以进行压缩。
程序包Package
若要将中间件包含在项目中,请添加对AspNetCore 元包的引用,其中包括AspNetCore. ResponseCompression包。
配置Configuration
下面的代码演示如何为默认 MIME 类型和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、 Firebug或Postman等工具设置
Accept-Encoding
请求标头,并研究响应标头、大小和正文。
将请求提交到没有 Accept-Encoding
标头的示例应用,并观察响应是否未压缩。响应中不存在 Content-Encoding
和 Vary
标头。
将请求提交到带有 Accept-Encoding: gzip
标头的示例应用,并观察响应是否已压缩。响应中存在 Content-Encoding
和 Vary
标头。
提供程序Providers
Gzip 压缩提供程序Gzip Compression Provider
使用 GzipCompressionProvider 压缩具有Gzip 文件格式的响应。
如果未将压缩提供程序显式添加到 CompressionProviderCollection:
- 默认情况下,将 Gzip 压缩提供程序添加到压缩提供程序的数组。
- 当客户端支持 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),这可能不会生成最有效的压缩。如果需要最有效的压缩,请将中间件配置为最佳压缩。
Compression Level | 说明 |
---|---|
CompressionLevel | 压缩应该尽快完成,即使生成的输出未以最佳方式压缩。 |
CompressionLevel. NoCompression | 不应执行压缩。 |
CompressionLevel | 即使压缩需要更长的时间,也应以最佳方式压缩响应。 |
public void ConfigureServices(IServiceCollection services)
{
services.AddResponseCompression();
services.Configure<GzipCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.Fastest;
});
}
自定义提供程序Custom providers
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 types
中间件为压缩指定了一组默认的 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 横幅图像(横幅)进行压缩和服务。
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" });
});
}
安全协议压缩Compression with secure protocol
可以使用默认情况下禁用 EnableForHttps
选项控制安全连接上的压缩响应。在动态生成的页面中使用压缩可能会导致安全问题,例如犯罪)和漏洞)攻击。
添加 Vary 标头Adding the Vary header
根据 Accept-Encoding
标头压缩响应时,可能会有多个压缩版本的响应和未压缩的版本。为了指示客户端和代理缓存有多个版本存在且应该存储,将使用 Accept-Encoding
的值添加 Vary
标头。在 ASP.NET Core 2.0 或更高版本中,在对响应进行压缩时,中间件会自动添加 Vary
标头。
Nginx 反向代理后的中间件问题Middleware issue when behind an Nginx reverse proxy
当 Nginx 代理请求时,将删除 Accept-Encoding
标头。删除 Accept-Encoding
标头会阻止中间件压缩响应。有关详细信息,请参阅NGINX:压缩和解压缩。此问题通过Nginx 的传递压缩(aspnet/BasicMiddleware #123)进行跟踪。
使用 IIS 动态压缩Working with IIS dynamic compression
如果在要为应用禁用的服务器级别上配置了活动的 IIS 动态压缩模块,请使用web.config文件的附加功能禁用该模块。有关详细信息,请参阅禁用 IIS 模块。
故障排除Troubleshooting
使用Fiddler、 Firebug或Postman之类的工具,通过该工具,可以设置 Accept-Encoding
请求标头并研究响应标头、大小和正文。默认情况下,响应压缩中间件会压缩满足以下条件的响应:
Accept-Encoding
标头存在,其值为gzip
、*
或自定义编码,此值与已建立的自定义压缩提供程序匹配。该值不能为identity
,或者其质量值(qvalue,q
)设置为0(零)。- 必须设置 MIME 类型(
Content-Type
),并且该类型必须与 ResponseCompressionOptions上配置的 MIME 类型匹配。 - 请求不能包含
Content-Range
标头。 - 除非在响应压缩中间件选项中配置了安全协议(https),否则请求必须使用不安全的协议(http)。启用安全内容压缩时,请注意上面所述的危险。