ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、视频、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## HTTP的传输编码(Transfer-Encoding:chunked) ### 什么是传输编码? 传输编码在 HTTP 的报文头中,使用`Transfer-Encoding`首部进行标记,它就是指明当前使用的传输编码。 `Transfer-Encoding`会改变报文的格式和传输的方式,使用它不但不会减少内容传输的大小,甚至还有可能会使传输变大,看似是一个不环保的做法,但是其实是为了解决一些特殊问题。 简单来说,传输编码必须配合持久连接去使用,为了在一个持久连接中,将数据分块传输,并标记传输结束而设计的,后面会详细讲解。 在早年间的设计里,和内容编码使用`Accept-Encoding`来标记客户端接收的压缩编码类型一样,传输编码还需要配合`TE`这个请求报文头来使用,用于指定支持的传输编码。但是在最新的 HTTP/1.1 协议规范中,只定义了一种传输编码:分块编码(chunked),所以并不需要再依赖`TE`这个头部。 这些细节,后面都会讲到。既然传输编码和持久连接是息息相关的,那我们就先来了解一下什么是持久连接。 ### 持久连接(Persistent Connection) 持久连接通俗来讲,就是长连接,英文叫 Persistent Connection,其实按字面意思理解就好了。 在早期的 HTTP 协议中,传输数据的顺序大致分为发起请求、建立连接、传输数据、关闭连接等步骤,而持久连接,就是去掉关闭连接这个步骤,让客户端和服务端可以继续通过此次连接传输内容。 这其实也是为了提高传输效率,我们知道 HTTP 协议是建立在 TCP 协议之上的,自然有 TCP 一样的三次握手、慢启动等特性,这样每一次连接其实都是一次宝贵的资源。为了尽可能的提高 HTTP 的性能,使用持久连接就显得很重要了。为此在 HTTP 协议中,就引入了相关的机制。 在早期的 HTTP/1.0 协议中并没有持久连接,持久连接的概念是在后期才引入的,当时是通过`Connection:Keep-Alive`这个头部来标记实现,用于通知客户端或服务端相对的另一端,在发送完数据之后,不要断开 TCP 连接,之后还需要再次使用。 而在 HTTP/1.1 协议中,发现持久连接的重要性了,它规定所有的连接必须都是持久的,除非显式的在报文头里,通过`Connection:close`这个首部,指定在传输结束之后会关闭此连接。 实际上在 HTTP/1.1 中`Connect`这个头部已经没有`Keep-Alive`这个取值了,由于历史原因,很多客户端和服务端,依然保留了这个报文头。 长连接带来了另外一个问题,如何判定当前数据发送完成。 ### 判断传输完成 在早期不支持持久连接的时候,其实是可以依靠连接断开来判定当前传输已经结束,大部分浏览器也是这么干的,但这并不是规范的操作。应该使用`Content-Length`这个头部,来指定当前传输的实体内容长度。 下面举个例子,在保持持久连接的情况下,依赖`Content-Length`来确定数据发送完毕。