ASP.NET Core中的响应压缩的实现
副标题[/!--empirenews.page--]
响应压缩技术是目前Web开发领域中比较常用的技术,在带宽资源受限的情况下,使用压缩技术是提升带宽负载的首选方案。我们熟悉的Web服务器,比如IIS、Tomcat、Nginx、Apache等都可以使用压缩技术,常用的压缩类型包括Brotli、Gzip、Deflate,它们对CSS、JavaScript、HTML、XML 和 JSON等类型的效果还是比较明显的,但是也存在一定的限制对于图片效果可能没那么好,因为图片本身就是压缩格式。其次,对于小于大约150-1000 字节的文件(具体取决于文件的内容和压缩的效率,压缩小文件的开销可能会产生比未压缩文件更大的压缩文件。在ASP.NET Core中我们可以使用非常简单的方式来使用响应压缩。 使用方式# 在ASP.NET Core中使用响应压缩的方式比较简单。首先,在ConfigureServices中添加services.AddResponseCompression注入响应压缩相关的设置,比如使用的压缩类型、压缩级别、压缩目标类型等。其次,在Configure添加app.UseResponseCompression拦截请求判断是否需要压缩,大致使用方式如下 public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddResponseCompression(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseResponseCompression(); } } 如果需要自定义一些配置的话还可以手动设置压缩相关 public void ConfigureServices(IServiceCollection services) { services.AddResponseCompression(options => { //可以添加多种压缩类型,程序会根据级别自动获取最优方式 options.Providers.Add<BrotliCompressionProvider>(); options.Providers.Add<GzipCompressionProvider>(); //添加自定义压缩策略 options.Providers.Add<MyCompressionProvider>(); //针对指定的MimeType来使用压缩策略 options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat( new[] { "application/json" }); }); //针对不同的压缩类型,设置对应的压缩级别 services.Configure<GzipCompressionProviderOptions>(options => { //使用最快的方式进行压缩,单不一定是压缩效果最好的方式 options.Level = CompressionLevel.Fastest; //不进行压缩操作 //options.Level = CompressionLevel.NoCompression; //即使需要耗费很长的时间,也要使用压缩效果最好的方式 //options.Level = CompressionLevel.Optimal; }); } 关于响应压缩大致的工作方式就是,当发起Http请求的时候在Request Header中添加Accept-Encoding:gzip或者其他你想要的压缩类型,可以传递多个类型。服务端接收到请求获取Accept-Encoding判断是否支持该种类型的压缩方式,如果支持则压缩输出内容相关并且设置Content-Encoding为当前使用的压缩方式一起返回。客户端得到响应之后获取Content-Encoding判断服务端是否采用了压缩技术,并根据对应的值判断使用了哪种压缩类型,然后使用对应的解压算法得到原始数据。 源码探究# 通过上面的介绍,相信大家对ResponseCompression有了一定的了解,接下来我们通过查看源码的方式了解一下它大致的工作原理。 AddResponseCompression# 首先我们来查看注入相关的代码,具体代码承载在ResponseCompressionServicesExtensions扩展类中[点击查看源码👈] public static class ResponseCompressionServicesExtensions { public static IServiceCollection AddResponseCompression(this IServiceCollection services) { services.TryAddSingleton<IResponseCompressionProvider, ResponseCompressionProvider>(); return services; } public static IServiceCollection AddResponseCompression(this IServiceCollection services, Action<ResponseCompressionOptions> configureOptions) { services.Configure(configureOptions); services.TryAddSingleton<IResponseCompressionProvider, ResponseCompressionProvider>(); return services; } } 主要就是注入ResponseCompressionProvider和ResponseCompressionOptions,首先我们来看关于ResponseCompressionOptions[点击查看源码👈] public class ResponseCompressionOptions { // 设置需要压缩的类型 public IEnumerable<string> MimeTypes { get; set; } // 设置不需要压缩的类型 public IEnumerable<string> ExcludedMimeTypes { get; set; } // 是否开启https支持 public bool EnableForHttps { get; set; } = false; // 压缩类型集合 public CompressionProviderCollection Providers { get; } = new CompressionProviderCollection(); } 关于这个类就不做过多介绍了,比较简单。ResponseCompressionProvider是我们提供响应压缩算法的核心类,具体如何自动选用压缩算法都是由它提供的。这个类中的代码比较多,我们就不逐个方法讲解了,具体源码可自行查阅[点击查看源码👈],首先我们先看ResponseCompressionProvider的构造函数 public ResponseCompressionProvider(IServiceProvider services, IOptions<ResponseCompressionOptions> options) { var responseCompressionOptions = options.Value; _providers = responseCompressionOptions.Providers.ToArray(); //如果没有设置压缩类型默认采用Br和Gzip压缩算法 if (_providers.Length == 0) { _providers = new ICompressionProvider[] { new CompressionProviderFactory(typeof(BrotliCompressionProvider)), new CompressionProviderFactory(typeof(GzipCompressionProvider)), }; } //根据CompressionProviderFactory创建对应的压缩算法Provider比如GzipCompressionProvider for (var i = 0; i < _providers.Length; i++) { var factory = _providers[i] as CompressionProviderFactory; if (factory != null) { _providers[i] = factory.CreateInstance(services); } } //设置默认的压缩目标类型默认为text/plain、text/css、text/html、application/javascript、application/xml //text/xml、application/json、text/json、application/was var mimeTypes = responseCompressionOptions.MimeTypes; if (mimeTypes == null || !mimeTypes.Any()) { mimeTypes = ResponseCompressionDefaults.MimeTypes; } //将默认MimeType放入HashSet _mimeTypes = new HashSet<string>(mimeTypes, StringComparer.OrdinalIgnoreCase); _excludedMimeTypes = new HashSet<string>( responseCompressionOptions.ExcludedMimeTypes ?? Enumerable.Empty<string>(), StringComparer.OrdinalIgnoreCase ); _enableForHttps = responseCompressionOptions.EnableForHttps; } (编辑:拼字网 - 核心网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |