http 发展历史
HTTP/0.9
1991年
- 方法单一,只有 get 方法
- 服务器只能回复 HTML 格式的字符串
HTTP/1.0
1996年5月
- 任何格式的内容都可以发送,为互联网大发展奠定了基础
- 命令增加,引入 POST 和 HEAD 命令
- http 请求和回应的格式也变了。除了数据部分,每次通信都必须包括头信息(http header ) ,用来描述一些元数据。头信息必须是 ASCII 码
- 非标准的 connection: keep-alive tcp 复用
HTTP/1.1
1997年1月
- 新增方法 PUT、PATCH、OPTIONS、DELETE
- 持久连接 不需要声明 connection: keep-alive,允许在单个 tcp 连接上发送多个请求和响应,减少了每次请求的连接建立和断开开销
- 流水线传输(pipelining),支持请求和响应的流水线传输。同一个 tcp 连接里面,客户端可以同时发送多个请求(但是服务器只有处理完一个 response 才会处理下一个,可能造成“队头堵塞”)
- 分块传输编码(Chunked Transfer Encoding):HTTP 1.1 引入了分块传输编码,允许服务器将响应消息分成多个块进行传输,而不是等待整个响应消息完全生成。这对于传输大型响应或动态生成的响应非常有用,无需知道响应大小,每个chunck 自带长度,最后的chunck 长度为 0
- 缓存控制(Caching):HTTP 1.1 引入了更灵活的缓存控制机制,包括使用Cache-Control头字段指定缓存策略、使用ETag和If-None-Match字段支持条件请求等,以提高缓存效率和减少网络传输
HTTP/2
二进制协议
二进制分帧:HTTP/2 数据通信的最小单位消息:指 HTTP/2 中逻辑上的 HTTP 消息。例如请求和响应等,消息由一个或多个帧组成
流:存在于连接中的一个虚拟通道。流可以承载双向消息,每个流都有一个唯一的整数ID
二进制协议:HTTP/2使用二进制格式传输数据,而不是HTTP/1.x中的文本格式。这使得数据传输更加高效,并减少了解析的复杂性
多路复用
- HTTP/2引入了多路复用的概念,同域名下所有通信都在单个连接上完成
- 单个连接可以承载任意数量的双向数据流
- 将每个请求或响应的所有数据包,称为一个数据流(stream),数据流以消息(消息就是请求或响应)的形式发送,而消息又由一个或多个帧组成,多个帧之间可以乱序发送,因为根据帧首部的
流标识
(每个数据流都有一个独一无二的编号)可以重新组装 - 客户端发出的数据流,ID一律为奇数,服务器发出的,ID为偶数
- 解决http 1.1协议应用层队头阻塞问题
TIP
HTTP/2 的帧重组过程包括以下步骤:
- 接收端接收到多个帧,并根据帧头部的标识信息,将它们按照数据流进行分类
- 接收端根据帧头部的标识信息,将同一个数据流中的帧按照其发送的顺序进行排序
- 接收端根据帧头部的标识信息,将多个帧中的数据字段进行组合,还原出原始的数据
- 一旦整个数据流的帧都被接收并重组完整,接收端就可以将原始数据提供给上层应用进行处理
HPACK 算法
- 头部压缩:HTTP/2使用了HPACK算法对请求和响应的头部进行压缩,减少了数据传输的大小。这减少了网络带宽的消耗,并加快了页面加载速度
- TTP/2在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键-值对,对于相同的数据,不再通过每次请求和响应发送
- 首部表在HTTP/2的连接存续期内始终存在,由客户端和服务器共同渐进地更新
- 每个新的首部键-值对要么被追加到当前表的末尾,要么替换表中之前的值
- 重复出现的 header 传输其在“首部表”中的序号
服务端推送
- 服务器推送:HTTP/2支持服务器主动推送,即在客户端请求之前,服务器可以预先向客户端发送一些资源。这提高了资源获取的效率,减少了延迟
- 流量优先级:HTTP/2引入了流的概念,可以对流进行优先级设置,确保重要的请求和响应能够更快地传输