← 返回题目列表

HTTP 内容压缩是怎么工作的?Content-Encoding 和 Transfer-Encoding 有什么区别?

中等 第 23 / 32 题 更新于 2026/08/02
HTTP内容压缩响应优化

简化版

HTTP 内容压缩通常由客户端通过 Accept-Encoding 声明自己支持的算法,比如 gzipbrzstd,服务端选择一种算法压缩响应体,并用 Content-Encoding 告诉客户端如何解压。

Content-Encoding 描述的是实体内容本身的编码方式,客户端解压后得到原始资源;Transfer-Encoding 描述的是传输过程中的分帧方式,例如 chunked,它不等于业务内容压缩。

面试回答时要抓住 3 点:谁协商、压缩谁、和分块传输的边界。

详细版

客户端请求:

GET /app.js HTTP/1.1
Host: example.com
Accept-Encoding: gzip, br

服务端响应:

HTTP/1.1 200 OK
Content-Type: application/javascript
Content-Encoding: br
Vary: Accept-Encoding

这里表示响应体使用 Brotli 压缩,客户端需要先按 br 解压,再把内容当作 JavaScript 处理。

Content-Encoding 常见于静态资源、JSON、HTML、CSS、JS 等文本类内容。图片、视频、zip 等本身已经压缩过的资源通常收益很低,甚至可能变大。

Transfer-Encoding: chunked 是把响应体拆成一块一块传输,常见于无法提前知道 Content-Length 的场景。它解决的是“怎么传”,不是“内容是否压缩”。

压缩能减少网络传输字节数,但会增加 CPU 开销。高并发场景要权衡压缩等级、资源类型、缓存策略和网关/CDN 的处理能力。

完整版教学

1. 先把压缩协商链路讲清楚

HTTP 压缩不是服务端单方面决定的,它通常是一次协商。

客户端在请求头里告诉服务端:

Accept-Encoding: gzip, deflate, br

服务端根据浏览器支持情况、资源类型、资源大小、CPU 成本、网关配置选择一种编码。

响应时服务端再告诉客户端:

Content-Encoding: gzip

客户端看到这个响应头后,会先解压响应体,再交给上层解析。

面试时不要只说“gzip 压缩”,要补一句:HTTP 压缩通过 Accept-EncodingContent-Encoding 协商完成。

2. Content-Encoding 压缩的是资源表示

Content-Encoding 作用在 HTTP 实体内容上。

例如 /index.html 的原始内容是 HTML 文本,服务端可以把这份 HTML 用 gzip 压缩后发送。

客户端解压后看到的仍然是原来的 HTML。

这意味着它和 Content-Type 是两个不同维度:

响应头关注点示例作用
Content-Type内容类型text/html告诉客户端如何解释内容
Content-Encoding内容编码gzip告诉客户端如何还原内容
Content-Length字节长度10240通常表示编码后实体长度
Vary缓存维度Accept-Encoding告诉缓存按压缩能力区分副本

一个响应可以同时是 Content-Type: text/htmlContent-Encoding: br

3. Transfer-Encoding 关注传输过程

Transfer-Encoding 不是内容压缩语义,它描述消息体在连接上传输时采用的传输编码。

最常见的是:

Transfer-Encoding: chunked

它表示响应体被拆成多个 chunk,每个 chunk 前面带长度,最后用长度为 0 的块结束。

这通常发生在服务端无法提前知道完整响应长度时,例如边生成边返回。

所以二者的区别是:

对比项Content-EncodingTransfer-Encoding
作用对象资源实体内容HTTP 消息传输方式
典型值gzipbrzstdchunked
客户端处理解压得到原始表示组装消息体
是否影响缓存副本会影响通常不作为资源变体

4. 哪些内容适合压缩

适合压缩的内容通常有明显文本冗余。

  • HTML
  • CSS
  • JavaScript
  • JSON
  • XML
  • SVG

不太适合压缩的内容包括:

  • JPEG、PNG、WebP 等图片
  • MP4、MP3 等媒体文件
  • zip、gz、rar 等压缩包

原因是它们已经经过压缩算法处理,再压缩收益小,还会浪费 CPU。

5. 压缩与缓存要一起考虑

如果 CDN 或浏览器缓存了压缩后的响应,就必须知道这个副本是面向哪类客户端的。

例如支持 Brotli 的浏览器可以接收 br,旧客户端可能只能接收 gzip

所以服务端一般要加:

Vary: Accept-Encoding

这告诉中间缓存:同一个 URL 不能只按 URL 缓存,还要按请求里的 Accept-Encoding 区分不同版本。

如果缺少 Vary,可能出现支持能力不同的客户端拿到错误编码内容的问题。

6. 性能收益与成本

压缩减少的是网络传输字节数,代价是 CPU 计算。

在弱网、跨地域、移动端场景,压缩收益通常很明显。

在内网、高 QPS、CPU 已经紧张的接口上,要谨慎设置压缩等级。

常见工程策略是:

  • 小于 1KB 的响应不压缩,避免收益太低。
  • 已压缩格式不再压缩。
  • 静态资源预压缩,提前生成 .gz.br
  • 动态接口使用较低压缩等级。
  • CDN 边缘节点承担部分压缩工作。

7. 常见误区与追问

  • 误区:Content-Encoding 和 Content-Type 是一回事。 前者说明如何还原内容,后者说明还原后如何解释内容。
  • 误区:Transfer-Encoding: chunked 就是 gzip。 chunked 是分块传输,gzip 是内容压缩。
  • 误区:所有资源都应该压缩。 图片、视频和压缩包再次压缩通常收益很低。
  • 追问:Content-Length 表示压缩前还是压缩后的长度? 通常表示实际传输实体的长度,也就是编码后的字节数。
  • 追问:为什么压缩响应常配 Vary: Accept-Encoding? 因为不同客户端支持的压缩算法不同,缓存必须区分副本。
  • 追问:Brotli 一定比 gzip 好吗? Brotli 压缩率常更高,但压缩成本和兼容性也要考虑。

8. 加强记忆

记住这条线:Accept-Encoding 是客户端报能力,Content-Encoding 是服务端报内容怎么解,Transfer-Encoding 是连接上怎么传。

面试里可以用 3 个词收束:协商、实体、传输。