为什么 app.UseResponseCompression() 会增加通过网络传输的响应的大小?

Gui*_*rme 3 c# compression asp.net-core

我正在尝试使用一个非常简单的 Asp.Net Core 3.1 应用程序启用响应压缩。我当前的代码:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<BrotliCompressionProviderOptions>(options => options.Level = CompressionLevel.Optimal);
        services.AddResponseCompression(options =>
        {
            options.Providers.Add<BrotliCompressionProvider>();
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        app.UseResponseCompression();
        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapGet("/", async context =>
            {
                var text = File.ReadAllText(@"D:\huge-response.txt");
                await context.Response.WriteAsync(text);
            });
        });
    }
Run Code Online (Sandbox Code Playgroud)

在巨大的响应.txt 文件中,我有以下内容:

qwer qwert qwert qwert qwert
qwer qwert qwert qwert qwert
qwer qwert qwert qwert qwert
qwer qwert qwert qwert qwert
qwer qwert qwert qwert qwert
qwer qwert qwert qwert qwert
....
Run Code Online (Sandbox Code Playgroud)

重复了很多次。该文件为 626 KB。

现在,让我们看看 Chrome 对此有何评论:

在此输入图像描述

奇怪的。那么让我们在 Fiddler 中看看。第一个请求是“正常”的,第二个请求是带有标头的Accept-Encoding: br

在此输入图像描述

我也尝试过Gzip压缩,结果基本相同。

这与我想象的情况几乎相反。即使在“最快”的配置中,这样的文本文件也应该具有可笑的可压缩性。我预计通过网络传输的数据量将少于 1 KB。

我究竟做错了什么?提前致谢。

小智 9

app.UseResponseCompression();中间件仅适用于Content-Type呈现MIME 类型,而HttpResponse不是像HttpResponse您正在做的那样写入文件流。

按照文档,您将看到这一行:

Content-Type:指定内容的 MIME 类型。每个响应都应指定其内容类型。中间件检查该值以确定是否应压缩响应。中间件指定一组可以编码的默认 MIME 类型,但您可以替换或添加 MIME 类型。

如果您想压缩自定义文件,您需要编写带有Content-Type标头的文件流。然后当这个响应返回到ResponseCompression中间件时,它将被压缩。

public async Task Invoke(HttpContext context)
{
    context.Response.ContentType = "text/plain";
    using (var fs = new FileStream(@"D:\huge-response.txt", FileMode.Open))
    {
        await fs.CopyToAsync(context.Response.Body);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 即使没有文件流,添加 `context.Response.ContentType = "text/plain";` 也能工作。我现在为 20MB 的文本获取 200 字节的网络流量。 (2认同)