这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天
课程重点
- HTTP 协议的基本定义
- HTTP 协议主要特征
- HTTP 协议发展历程
- HTTP 协议的报文结构
HTTP 协议的基本定义
HTTP 协议是 HyperText Transfer Protocol 的缩写,即超文本传输协议,它是一种基于 TCP/IP 通信协议来传递数据(HTML 文件,图片文件,查询结果等)的规则,由于 HTTP 协议属于应用层协议,所以它必须建立在 TCP/IP 协议之上,但是,它与 TCP/IP 协议又有所不同,它是一个独立的协议,但是它的设计参考了 TCP/IP 协议。
HTTP 协议主要特征
无状态
HTTP协议是无状态的,HTTP 协议自身不对请求和响应之间的通信状态进行保存,任何两次请求之间都没有依赖关系。直观地说,就是每个请求都是独立的,与前面的请求和后面的请求都是没有直接联系的。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意将HTTP协议如此设计。
简单快速
在用户向服务器请求服务时,只需传送请求方法和路径,不需要发送额外过多的数据。请求方法常用的有GET、HEAD、PUT、DELETE、POST。每种方法规定了客户与服务器联系的类型不同。并且由于HTTP协议结构较为简单,使得HTTP服务器的程序规模小,因此通信速度很快。
灵活
HTTP协议对数据对象并没有要求,允许传输任意类型的数据对象。对于正在传输的数据类型,HTTP协议将通过Content-Type进行标记。
无连接
无连接的含义是对于连接加以限制,每次连接都只会对一个请求进行处理,当服务器对客户的请求处理完毕并收到客户的应答后,就会直接断开连接。HTTP协议采用这种方式可以大大节省传输时间,提高传输效率。
HTTP 协议发展历程
HTTP/0.9
在 1990 年 ,蒂姆·伯纳斯-李创建了运行万维网所需的所有工具,其中包括HTTP。那时候是互联网初期,计算机的处理能力包括网速等等都很弱,所以 HTTP 也逃脱不了那个时代的约束,因此设计的非常简单,而且也是纯文本格式。
因此只有 “GET”,也不需要啥请求头,并且拿完了就结束了,因此请求响应之后连接就断了。这时候的 HTTP 还没有版本号的,之所以称之为 HTTP / 0.9 是后人加上去了,为了区别之后的版本。
HTTP/1.0
随着图像和音频的发展,1995年Apache诞生(HTTP 服务器),浏览器也在不断的进步予以支持,这也促进了 HTTP 协议的修改。为了添加各种特性来满足用户的需求, 于 1996 年正式发布。
增加了以下几点:
- 增加了 HEAD、POST 等新方法。
- 增加了响应状态码。
- 引入了头部,即请求头和响应头。
- 在请求中加入了 HTTP 版本号。
- 引入了 Content-Type ,使得传输的数据不再限于文本。
HTTP/1.1
从 1995 年至 1999 年间的第一次浏览器大战,极大的推动了 Web 的发展。主要是因为 HTTP/1.0 很大的性能问题,就是每请求一个资源都得新建一个 TCP 连接,而且只能串行请求。
增加了以下几点:
- 新增持久连接keep-alive,目的是复用TCP连接;
- 支持 pipeline,无需等待前面的请求响应,即可发送第二次请求。
- 允许响应数据分块(chunked),即响应的时候不标明Content-Length,客户端就无法断开连接,直到收到服务端的 EOF ,利于传输大文件。
- 新增缓存的控制和管理。
- 加入了 Host 头,用在你一台机子部署了多个主机,然后多个域名解析又是同一个 IP,此时加入了 Host 头就可以判断你到底是要访问哪个主机。
HTTP/1.1存在的问题
总结主要有以下两点:
- 头阻塞:HTTP/1.1中只有收到当前请求响应后才能重用当前tcp连接发送下一次请求。虽然HTTP/1.1提出了pipeline,旨在缓解这个问题。但是一方面pipeline在复杂的网络环境下很难实现和普及,其次就算都用上了pipeline,pipeline也只是使得可以在本次响应完成之前可以发送下次请求,但响应依然要严格按照顺序返回,也就是如果前一个响应被阻塞,后边的响应将不会到来,头阻塞问题还是没有完全解决。目前客户端(比如浏览器)一般会同时打开多个tcp连接来绕开头阻塞的问题,chrome默认会打开6个tcp链接,并发请求各种类型数据。但是这就带来了一个矛盾,tcp链接越多,肯定对资源的浪费是越大的,链接越少,头阻塞的问题就会越突出。
- 重复的未压缩头数据的传输:自HTTP/1.1之后,HTTP请求中通常带有大量ASCII编码的头部,这些头部通常大部分不会变化,需要每次请求都携带(尤其像是User Agent、Cookie这些值比较长的头部字段),会给本来就拥挤的网络带来很大的压力。
除此之外还有一些问题,比如TCP 的慢启动,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度,而大量http的业务请求其实本身都只是短链接的,所以导致tcp的流量控制算法没有很好的应用。为此,HTTP/2的出现就很有必要了。
HTTP/2.0
随着 HTTP/1.1 的发布,互联网也开始了爆发式的增长,这种增长暴露出 HTTP 的不足,主要还是性能问题,而 HTTP/1.1 无动于衷。互联网标准化组织以 Google 推出的SPDY 协议为基础开始制定新版本的 HTTP 协议,最终在 2015 年发布了 HTTP/2。
增加了以下几点:
- 是二进制协议,不再是纯文本。(解析数据开销更小,减少了网络延迟,提升了整体的吞吐量)
- 支持一个 TCP 连接发起多请求,即支持多路复用,移除了 pipeline。(HTTP/1.1 pipeline 还是有阻塞的情况,需要等前面的一个响应返回了后面的才能返回。)
- 利用 HPACK 压缩头部(减少数据传输量。)
- 允许服务端主动推送数据。(其实就是减少了请求的次数)
HTTP/2 引入了一个新的二进制分帧层,该层无法与之前的 HTTP/1.x 服务器和客户端兼容,HTTP/2的新特性都是建立在这个二进制分帧层基础之上的。
HTTP/3.0
这次的痛点来自于 HTTP 依赖的是可靠的、有序的,具有失败重传和按序机制的传输协议 TCP。
依赖TCP存在的问题:
- HTTP/2 是所有流共享一个 TCP 连接,所以会有 TCP 层面的队头阻塞,当发生重传时会影响多个请求响应;
- TCP 是基于四元组(源IP,源端口,目标IP,目标端口)来确定连接的,而在移动网络的情况下 IP 地址会频繁的换,这会导致反复的建连;
- TCP 与 TLS 的叠加握手,增加了延时
因此 Google 把 TCP 可靠、有序、丢包重传和拥塞控制功能提到应用层来实现,就研究出了基于 UDP 的 QUIC 协议。在 2018 年,互联网标准化组织 IETF 提议将 HTTP over QUIC 更名为 HTTP/3 并获得批准。
增加了以下几点:
- 基于UDP,并把 TCP 可靠、有序、丢包重传和拥塞控制功能提到应用层来实现;
- 引入了个叫 Connection ID 来标识一个链接,所以切换网络之后可以复用这个连接,达到 0 RTT 就能开始传输。
- 开发了QPACK 压缩头部,也采用了静态表、动态表和哈夫曼编码。(因为无法使用依赖TCP的HPACK)
HTTP 协议的报文结构
请求方式
常用请求头
场景分析
静态资源
登录案例
ajax与xhr
node http模块
扩展通信WebSocket