http accept-encoding详解 HTTP协议-压缩(gzip,deflate)

本文深入介绍了HTTP压缩的概念,包括其与HTTP内容编码的区别,详细阐述了压缩过程,并通过Fiddler工具进行了实战演示。内容强调了gzip压缩的优缺点,展示了如何通过Fiddler观察HTTP请求和响应的压缩状态,以及UnityWebRequest在HTTP请求中的压缩应用。此外,还讨论了解压缩的实现和JSON数据解析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文会使用Fiddler来查看HTTP request和Response, 如果不熟悉这个工具,可以先参考[Fiddler教程]

HTTP压缩是指: Web服务器和浏览器之间压缩传输的”文本内容“的方法。 HTTP采用通用的压缩算法,比如gzip来压缩HTML,Javascript, CSS文件。 能大大减少网络传输的数据量,提高了用户显示网页的速度。当然,同时会增加一点点服务器的开销。 本文从HTTP协议的角度,来理解HTTP压缩这个概念。

 
阅读目录

  1. HTTP内容编码和HTTP压缩的区别
  2. HTTP压缩的过程
  3. 实例:用Fiddler观察HTTP压缩
  4. 内容编码类型
  5. 压缩的好处
  6. gzip的缺点
  7. gzip是如何压缩的
  8. HTTP Response能压缩,HTTP Request也是可以压缩的


HTTP内容编码和HTTP压缩的区别

HTTP压缩,在HTTP协议中,其实是内容编码的一种。

在http协议中,可以对内容(也就是body部分)进行编码, 可以采用gzip这样的编码。 从而达到压缩的目的。 也可以使用其他的编码把内容搅乱或加密,以此来防止未授权的第三方看到文档的内容。

所以我们说HTTP压缩,其实就是HTTP内容编码的一种。 所以大家不要把HTTP压缩和HTTP内容编码两个概念混淆了。


HTTP压缩的过程

1. 浏览器发送Http request 给Web服务器,  request 中有Accept-Encoding: gzip, deflate。 (告诉服务器, 浏览器支持gzip压缩)

2. Web服务器接到request后, 生成原始的Response, 其中有原始的Content-Type和Content-Length。

3. Web服务器通过Gzip,来对Response进行编码, 编码后header中有Content-Type和Content-Length(压缩后的大小), 并且增加了Content-Encoding:gzip.  然后把Response发送给浏览器。

4. 浏览器接到Response后,根据Content-Encoding:gzip来对Response 进行解码。 获取到原始response后, 然后显示出网页。


如下图:


实例:Fiddler观察HTTP压缩

眼见为实, 我们看一个实际的例子, 我发现博客园就使用了gzip压缩。

使用Fiddler可以清楚地看到。  

在Fiddler中,每次都要手动去decode. 太麻烦。  点击工具栏上的"Decode"按钮,就可以自动decode了。


内容编码类型

 HTTP定义了一些标准的内容编码类型,并允许用扩展的形式添加更多的编码。

Content-Encoding header 就用这些标准化的代号来说明编码时使用的算法

Content-Encoding值

gzip  表明实体采用GNU zip编码

compress 表明实体采用Unix的文件压缩程序

deflate  表明实体是用zlib的格式压缩的

identity  表明没有对实体进行编码。当没有Content-Encoding header时, 就默认为这种情况

gzip, compress, 以及deflate编码都是无损压缩算法,用于减少传输报文的大小,不会导致信息损失。 其中gzip通常效率最高, 使用最为广泛。


压缩的好处

 http压缩对纯文本可以压缩至原内容的40%, 从而节省了60%的数据传输。

 实例: 博客园首页压缩前是:46124 bytes. 压缩后是:16368bytes.     只有原先的35%。  节省了65%的数据传输,从而大大提高了性能

 有图为证。


Gzip的缺点

JPEG这类文件用gzip压缩的不够好。


Gzip是如何压缩的

简单来说, Gzip压缩是在一个文本文件中找出类似的字符串, 并临时替换他们,使整个文件变小。这种形式的压缩对Web来说非常适合, 因为HTML和CSS文件通常包含大量的重复的字符串,例如空格,标签。


HTTP Response能压缩,HTTP Request也是可以压缩的

浏览器是不会对Request压缩的。 但是 一些HTTP程序在发送Request时,会对其进行编码。 如下图。

http可以用www和UnityWebRequest,但是www已经被弃用,建议使用UnityWebRequest;

直接上代码

      UnityWebRequest uwr = UnityWebRequest.Get("www.baidu.com"); //创建UnityWebRequest对象
        uwr.timeout = 20;
        yield return uwr.SendWebRequest();                                
        if (uwr.isHttpError || uwr.isNetworkError)                        
        {
            print(uwr.error); //打印错误原因
        }
        else //请求成功
        {
            print("Get:请求成功");
        }

Gzip解压缩

由于我们的后台接口用了gzip压缩,所以没办法直接解析数据,需要先解压缩,找了几种压缩方式都不太好用,最后在用了框架中的方法,

库:using System.IO.Compression

       string str = "";//声明空字符串用来接收解压缩后的数据
            if (uwr.GetResponseHeader("Content-Encoding") != null && uwr.GetResponseHeader("Content-Encoding").ToLower().Equals("gzip"))
            {//判断是否被gzip压缩,是做解压缩操作,否直接接受text数据
                Stream ff = null;
                ff = new GZipStream(new MemoryStream(uwr.downloadHandler.data), CompressionMode.Decompress);
                using (StreamReader reader = new StreamReader(ff, Encoding.UTF8))
                {
                    str = reader.ReadToEnd();
                }
                print("Get:结果");
            }
            else
            {
                print("else");
                str = uwr.downloadHandler.text;
            }
            print(str);//输出解压缩后的字符串

Json解析

json解析时候遇到了坑,不知道什么原因直通过键值和数组index找到目标数据一直报错,后来我逐层解析才拿到数据,所以就数组和字典不要混合取值,多接几次数据就可以了。

JsonData data = JsonMapper.ToObject(content);
        JsonData list = data["key1"]["key2"];
        print("list=" + list.Count);
        JsonData dic = list[0];
        print("dic=" + dic);
        JsonData listData = dic["key3"];
        print("listData=" + listData.Count);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值