NET 6 webapi自定义响应压缩

压缩可以大大的降低我们服务器的响应速度,从而提高我们网页的加载速度,同时节省一定的带宽。分享一个开发小程序接口压缩过程中遇到部分机型不支持压缩的解决方案。

使用方式

在ASP.NET 6中使用响应压缩的方式比较简单。

首先,在Program.cs中添加builder.Services.AddResponseCompression注入响应压缩相关的设置,比如使用的压缩类型、压缩级别、压缩目标类型等。

其次,在Program.cs添加app.UseResponseCompression拦截请求判断是否需要压缩,大致使用方式如下:


builder.Services.AddResponseCompression(options =>
{
    options.Providers.Add<BrotliCompressionProvider>();
    options.Providers.Add<GzipCompressionProvider>();
    //针对指定的MimeType来使用压缩策略
    options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "application/json" });
    options.EnableForHttps = true;
});

//针对不同的压缩类型,设置对应的压缩级别
builder.Services.Configure<BrotliCompressionProviderOptions>(options =>
{
    //使用最优的方式进行压缩,即使花费的时间较长
    options.Level = CompressionLevel.Optimal;

    //使用最快的方式进行压缩,不一定是压缩效果最好的方式
    //options.Level = CompressionLevel.Fastest;

    //使用尽可能小的输出的方式进行压缩,即使花费的时间较长
    //options.Level = CompressionLevel.SmallestSize;
});

...
...
...

//使用接口压缩
app.UseResponseCompression();

问题

上面的方法绝大多数就能满足压缩需求,但是有时候会出现一些奇葩的需求和问题,例如部分国产机型在使用小程序的时候请求头是支持压缩的,但是返回压缩数据后出现无法解析的情况,这个时候如果不想放弃压缩,就需要使用自定义压缩类型CompressionProvider

实现思路

前端初始访问后端验证接口,验证是否支持压缩格式,将验证后结果放在Headers头请求,遇到不支持的可以直接返回未压缩的内容。


    /// <summary>
    /// 自定义压缩,采用默认压缩
    /// </summary>
    public class CompressionProvider : ICompressionProvider
    {
        public CompressionProvider(IOptions<BrotliCompressionProviderOptions> options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            Options = options.Value;
        }

        private BrotliCompressionProviderOptions Options { get; }

        /// <inheritdoc />
        public string EncodingName { get; } = "br";

        /// <inheritdoc />
        public bool SupportsFlush => true;

        /// <inheritdoc />
        public Stream CreateStream(Stream outputStream)
        {
            HttpContextAccessor context = new();
            if (context.HttpContext != null)
            {
                //放过验证的接口,每次都需要压缩返回
                if (context.HttpContext.Request.Path.Value.ToLower().Equals("/api/common/checkcompression"))
                {
                    return new BrotliStream(outputStream, Options.Level, leaveOpen: true);
                }

                var compression = context.HttpContext.Request.Headers.ContainsKey("Compression") ? context.HttpContext.Request.Headers["Compression"].FirstOrDefault() : null;

                if (!string.IsNullOrEmpty(compression) && compression.ToLower().Equals("compression"))
                {
                    return new BrotliStream(outputStream, Options.Level, leaveOpen: true);
                }
            }

            return new BrotliStream(outputStream, CompressionLevel.NoCompression, leaveOpen: true);
        }
    }
    

builder.Services.AddResponseCompression(options =>
{
    //自定义压缩类型
    options.Providers.Add<CompressionProvider>();
    //针对指定的MimeType来使用压缩策略
    options.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(new[] { "application/json" });
    options.EnableForHttps = true;
});

//针对不同的压缩类型,设置对应的压缩级别
builder.Services.Configure<BrotliCompressionProviderOptions>(options =>
{
    //使用最优的方式进行压缩,即使花费的时间较长
    options.Level = CompressionLevel.Optimal;

    //使用最快的方式进行压缩,不一定是压缩效果最好的方式
    //options.Level = CompressionLevel.Fastest;

    //使用尽可能小的输出的方式进行压缩,即使花费的时间较长
    //options.Level = CompressionLevel.SmallestSize;
});

...
...
...

//使用接口压缩
app.UseResponseCompression();

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值