GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNIX系统的文件压缩。我们在Linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式,或者说一种文件格式。HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。
在 HTTP 传输时是支持 gzip 压缩的,客户端发起请求时在请求头里增加 Accept-Encoding: gzip,服务端响应时在返回的头信息里增加 Content-Encoding: gzip,这表示传输的数据是采用 gzip 压缩的。默认情况下,传输内容是不压缩的,采用gzip压缩可以大幅减少传输内容大小,这样可以提高传输速度,减少流量的使用。
通过内容协商的方式,服务端会选择一个客户端提议的方式,使用并在响应头 Content-Encoding 中通知客户端该选择。
HTTP请求头Accept-Encoding会将客户端能够理解的内容编码方式——通常是某种压缩算法——进行通知(给服务端)。
常见的取值类型有:
类型 | 含义 |
---|---|
gzip | gzip类型压缩 |
compress | 支持compress |
identity | 默认值,表示不需要进行任何编码 |
* | 匹配其他任意未在该请求头字段中列出的编码方式。 |
br | 表示采用 Brotli 算法的编码方式 |
deflate | 采用 zlib 结构和 deflate 压缩算法 |
在Android 2.3.3版本之后,HttpURLConnection发请求时,默认的request hearder里会加上 Accept-Encoding: gzip。
参见: http://developer.android.com/reference/java/net/HttpURLConnection.html
在Android4.4以后底层是由OkHttp实现的,所以4.4之后的版本,Content-Length被移除,getContentLength()为 -1。
我们可以手动设置"Accept-Encoding"字段,来解除针对gzip的默认行为。
OkHttp是默认支持gzip解压缩的,不需要额外配置的。
OkHttp会额外的增加很多请求头信息,如果我们在代码里没有手动设置Accept-Encoding = gzip ,那么OkHttp会自动处理gzip的解压缩。具体源码可以查看BridgeInterceptor这个类,如果header中没有Accept-Encoding,默认自动添加,且标记变量transparentGzip为true。
OkHttp在处理请求结果时,如果成功返回,并获取到内容,则移除Content-Encoding、Content-Length,并对结果进行解压缩。
在OkHttp中,如果在请求头添加addHeader(“Accept-Encoding”, “gzip, deflate”),Okhttp不会帮你处理Gzip的解压,需要你自己去处理。
OkHttp默认使用gzip压缩,但是会把返回数据的大小length修改为-1,我们如果想获取一些进度或者大小相关的信息,就会出现问题,这时可以手动设置"Accept-Encoding"字段,手动来解析gzip压缩后的数据。