Connection: keep-alive,Content-Length,Transfer-Encoding: chunked,Content-Encoding: gzip等

  • Transfer-Encoding,是一个 HTTP 头部字段,字面意思是「传输编码」。
    用来改变报文格式,它不但不会减少实体内容传输大小,甚至还会使传输变大,那它的作用是什么呢?下面进行介绍。
  • HTTP 协议中还有另外一个头部与编码有关:Content-Encoding(内容编码)。
    Content-Encoding 通常用于对实体内容进行压缩编码,目的是优化传输,例如用 gzip 压缩文本文件,能大幅减小体积。
  • Content-Encoding 和 Transfer-Encoding 二者是相辅相成的,对于一个 HTTP 报文,很可能同时进行了内容编码和传输编码。
  • 介绍开始:
  • 我们知道 HTTP 运行在 TCP 连接之上,自然也有着跟 TCP 一样的三次握手、慢启动等特性,为了尽可能的提高 HTTP 性能,使用持久连接就显得尤为重要了。为此,HTTP 协议引入了相应的机制。
  • HTTP/1.0 的持久连接机制是后来才引入的,通过 Connection: keep-alive 这个头部来实现,服务端和客户端都可以使用它告诉对方在发送完数据之后不需要断开 TCP 连接,以备后用。HTTP/1.1 则规定所有连接都必须是持久的,除非显式地在头部加上 Connection: close。所以实际上,HTTP/1.1 中 Connection 这个头部字段已经没有 keep-alive 这个取值了,但由于历史原因,很多 Web Server 和浏览器,还是保留着给 HTTP/1.1 长连接发送 Connection: keep-alive 的习惯。
  • 浏览器重用已经打开的空闲持久连接,可以避开缓慢的三次握手,还可以避免遇上 TCP 慢启动的拥塞适应阶段,听起来十分美妙。
  • 对于非持久连接,浏览器可以通过连接是否关闭来界定请求或响应实体的边界;而对于持久连接,这种方法显然不奏效。尽管服务端已经发送完所有数据,但浏览器并不知道这一点,它无法得知这个打开的连接上是否还会有新数据进来,只能傻傻地等。
  • 要解决上面这个问题,最容易想到的办法就是计算实体长度,并通过头部告诉对方。这就要用到 Content-Length 了。
  • 由于 Content-Length 字段必须真实反映实体长度,但实际应用中,有些时候实体长度并没那么好获得。要想准确获取长度,只能开一个足够大的 buffer,等内容全部生成好再计算。但这样做一方面需要更大的内存开销,另一方面也会让客户端等更久。
  • 我们在做 WEB 性能优化时,有一个重要的指标叫 TTFB(Time To First Byte),它代表的是从客户端发出请求到收到响应的第一个字节所花费的时间。大部分浏览器自带的 Network 面板都可以看到这个指标,越短的 TTFB 意味着用户可以越早看到页面内容,体验越好。可想而知,服务端为了计算响应实体长度而缓存所有内容,跟更短的 TTFB 理念背道而驰。但在 HTTP 报文中,实体一定要在头部之后,顺序不能颠倒,为此我们需要一个新的机制:不依赖头部的长度信息,也能知道实体的边界。
  • Transfer-Encoding 正是用来解决上面这个问题的。
  • 历史上 Transfer-Encoding 可以有多种取值,为此还引入了一个名为 TE 的头部用来协商采用何种传输编码。但是最新的 HTTP 规范里,只定义了一种传输编码:分块编码(chunked)。
  • 分块编码相当简单,在头部加入 Transfer-Encoding: chunked 之后,就代表这个报文采用了分块编码。这时,报文中的实体需要改为用一系列分块来传输。每个分块包含十六进制的长度值和数据,长度值独占一行,长度不包括它结尾的 CRLF(\r\n),也不包括分块数据结尾的 CRLF。最后一个分块长度值必须为 0,对应的分块数据没有内容,表示实体结束。
  • Content-Encoding 和 Transfer-Encoding 二者经常会结合来用,其实就是针对 Transfer-Encoding 的分块再进行 Content-Encoding。
  • 以上内容参考链接:https://imququ.com/post/transfer-encoding-header-in-http.html
  • 普通的静态页面、图片之类的,一般是 Content-Length。
  • 如果要一边产生数据,一边发给客户端,WEB 服务器就需要使用"Transfer-Encoding: chunked"这样的方式来代替 Content-Length。
  • JSP页面有一个缓存大小,当输出数据的长度没有到达这个大小的时候,服务器是知道总的数据长度的,所以服务器会输出 content-length头。但如果超过缓存大小,服务器不能判断整个内容的大小,于是返回 Transfer-Encoding:chunked这个头信息。
  • 结合HTTP协议其他的特点,比如说Http1.1之前的不支持keep alive。那么可以得出以下结论:
  1. 在Http 1.0及之前版本中,content-length字段可有可无。
  2. 在http1.1及之后版本。如果是keep alive,则content-length和chunk必然是二选一。若是非keep alive,则和http1.0一样。content-length可有可无。

posted on 2017-05-19 11:24  cag2050  阅读(1124)  评论(0编辑  收藏  举报

导航