HTTP
无状态、无连接的应用层协议
HTTP 1.0
浏览器和服务器保持短暂的连接,浏览器的每次请求都需要与服务器建立一个 TCP 连接,服务器处理完成后立即断开 TCP 连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态)。
HTTP 1.1
发布于 1999 年,默认使用文本格式传输数据
长链接
默认包含 Connection: keep-alive
头,可以让客户端和服务端在一段时间内可以复用这个链接,无需再次建立链接。链接复用发生在应用层,且复用是串行的
支持请求管道化
基于 HTTP1.1 的长连接,使得请求管线化成为可能。管线化使得请求能够“并行”传输。虽然 HTTP1.1 支持管道化,但是服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容。
由于“管道化”技术存在各种各样的问题,所以很多浏览器要么根本不支持它,要么就直接默认关闭。
协议扩展切换
支持在请求头部域消息中包含 Upgrade
头并让客户端通过头部标识令服务器知道它能够支持其它备用通信协议的一种机制,服务器根据客户端请求的其它协议进行切换,切换后使用备用协议与客户端进行通信
缓存控制
新增 Cache-Control
字段,支持 max-age
用来表示相对过期时间;服务器也可以通过 Etag
和 Last-Modified
来判断是否从浏览器中加载文件,此时缓存的控制和判断将决定响应状态码是 200 还是 304。参考浏览器缓存章节
部分内容传输优化
引入了 range
头域支持超文本文件的部分传输。如允许请求一个文件的起始位置和偏移长度来进行文件内容的部分传输
Host 头处理
请求消息和响应消息都支持 Host
头域,且请求消息中如果没有 Host
头域会报告一个错误(400 Bad Request
)
错误通知的管理
新增了 24
个错误状态响应码,如 409(Conflict)
表示请求的资源与资源的当前状态发生冲突;410(Gone)
表示服务器上的某个资源被永久性的删除。
HTTP 2.0
- 采用完全的二进制格式来传输数据,其在网络中以帧的形式传播,多个帧在网络中形成了帧的传输网络流,即流式传播的。
- 使用
TCP
复用的方式来降低网络请求链接的建立和关闭的开销,多个请求可以通过一个链接来进行并发完成。复用发生在传输层,是帧的多路复用,不同文件的传输可以在一个TCP
连接中一起同时进行流式传播 - 支持传输流的优先级和流量控制机制
- 支持服务端推送
二进制分帧
通过在应用层和传输层之间增加一个二进制分帧层,突破了 HTTP1.1 的性能限制、改进传输性能。
多路复用(连接共享)
- 流(stream):已建立连接上的双向字节流。
- 消息:与逻辑消息对应的完整的一系列数据帧。
- 帧(frame):HTTP2.0 通信的最小单位,每个帧包含帧头部,至少也会标识出当前帧所属的流(stream id)。
所有的 HTTP2.0 通信都在一个 TCP 连接上完成,这个连接可以承载任意数量的双向数据流。每个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(stream id)重新组装。
头部压缩
使用 encoder 来减少需要传输的 header 大小,通讯双方各自 cache 一份 header fields 表,既避免了重复 header 的传输,又减小了需要传输的大小。高效的压缩算法可以很大的压缩 header,减少发送包的数量从而降低延迟。
在头部压缩技术中,客户端和服务器均会维护两份相同的静态字典和动态字典。在静态字典中,包含了常见的头部名称以及头部名称与值的组合。静态字典在首次请求时就可以使用。那么现在头部的字段就可以被简写成静态字典中相应字段对应的 index。而动态字典跟连接的上下文相关,每个 HTTP/2 连接维护的动态字典是不尽相同的。动态字典可以在连接中不听的进行更新。原本完整的 HTTP 报文头部的键值对或字段,由于字典的存在,现在可以转换成索引 index,在相应的端再进行查找还原,也就起到了压缩的作用。