摘要:极客时间《浏览器工作原理与实践》 浏览器中的网络学习笔记,HTTP/1、HTTP/2、HTTP/3
HTTP/1
HTTP/0.9
HTTP/0.9 用来在网络之间传递体积很小的 HTML 超文本内容,所以被称为超文本传输协议。
完整请求流程:
1、客户端先要根据 IP 地址、端口和服务器经过三次握手建立 TCP 连接
2、发送一个 GET 请求行的信息来获取 index.html 等页面
3、服务器接收请求信息之后,读取对应的 HTML 文件,并将数据以 ASCII 字符流返回给客户端
4、HTML 文档传输完成后,断开连接
HTTP/0.9 的三个特点:
1、只有一个请求行,没有请求头和请求体
2、服务器也没有返回头信息
3、使用 ASCII 字符流来传输文件内容
因为需求仅仅是传输 HTML 文件,所以整个过程都很简单
HTTP/1.0
后来万维网的高速发展带来了很多新的需求,支持多种类型的文件下载是 HTTP/1.0 的一个核心诉求,而且要支持多类型的文件格式。因此,HTTP/1.0 引入了请求头和响应头,在发起请求时候会通过 HTTP 请求头告诉服务器它期待服务器返回什么类型的文件、采取什么形式的压缩、提供什么语言的文件以及文件的具体编码。服务器接收到浏览器发送过来的请求头信息之后,会根据请求头的信息来准备响应数据。服务器返回数据时,会先返回响应头信息,最终浏览器需要根据响应头的信息来处理数据。通过请求头和响应头来实现了很多特性:状态码,Cache 机制,用户代理等。
HTTP/1.1
HTTP/1.1 又在 HTTP/1.0 的基础之上做了大量的更新:
1、改进持久连接
在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持,这样减少了 TCP 建立连接和断开链接的消耗。目前浏览器中对于同一个域名,默认允许同时建立 6 个 TCP 持久连接。
2、不成熟的 HTTP 管线化
持久连接减少了 TCP 的建立和断开次数,但只有前面的请求返回后才能进行下一次请求,如果某个请求一旦意外没有及时返回,那么会阻塞后面的请求,造成队头阻塞的问题。HTTP/1.1 中试图通过管线化的技术来解决队头阻塞的问题,将 HTTP 请求整批提交给服务器,但服务器仍是按顺序来响应,最终管线化技术被放弃了。
3、提供虚拟主机的支持
HTTP/1.1 的请求头中增加了 Host 字段,用来表示当前的域名地址,服务器可以根据不同的 Host 值做不同的处理。这样在一台物理主机上就可以绑定多个虚拟主机,每个虚拟主机都有自己的单独的域名,这些单独的域名都公用同一个 IP 地址。
4、对动态生成的内容提供了完美支持
很多页面的内容都是动态生成的,因此在传输数据之前并不知道最终的数据大小,导致浏览器不知道何时会接收完所有的文件数据。HTTP/1.1 引入 Chunk transfer 机制解决这个问题,服务器会将数据分割成若干个数据块,每个数据块发送时会附上这个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。
5、客户端 Cookie、安全机制
HTTP/2
HTTP/1 的缺陷
HTTP/1.1 对带宽的利用率却并不理想。带宽是指每秒最大能发送或者接收的字节数,每秒能发送的最大字节数称为上行带宽,每秒能够接收的最大字节数称为下行带宽。
HTTP/1.1 很难将带宽用满的原因:
1、TCP 的慢启动。TCP 连接建立之后,刚开始 TCP 协议会采用一个非常慢的速度去发送数据,然后慢慢加快发送数据的速度,直到发送数据的速度达到一个理想状态
2、TCP 连接之间相互竞争固定的带宽
3、HTTP/1.1 队头阻塞的问题。虽然能公用一个 TCP 管道,但是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。
多路复用
为了规避 TCP 的慢启动和 TCP 连接之间的竞争问题,HTTP/2 采用一个域名只使用一个 TCP 长连接和消除队头阻塞问题
HTTP/2 通过引入二进制分帧层实现了 HTTP 的多路复用技术:
HTTP/2 的请求和接收过程:
1、浏览器准备好请求数据,包括请求行、请求头和请求体
2、请求数据经过二进制分帧层处理之后,会被转换为一个个带有请求 ID 编号的帧,并通过协议栈将这些帧发送给服务器
3、服务器收到所有帧后,将所有相同 ID 的帧合并为一条完整信息
4、服务器处理请求,将响应数据,包括响应行、响应头和响应体分别发送至二进制分帧层
5、二进制分帧层将响应数据都转为携带 ID 的帧,并进过协议栈将这些帧发送给浏览器
6、浏览器接收到响应帧后,根据 ID 将帧数据提交给对应的请求
多路复用的好处就是客户端任何时候都可以将请求发送给服务器,而并不需要等待其他请求的完成,然后服务器也可以随时返回处理好的请求资源给浏览器。并且一帧一帧的传递数据有一个好处,就是当服务器收到一个优先级高的请求时,服务器可以暂停之前的请求来优先处理关键资源的请求。
其他特性
除了最核心的多路复用功能,还有其他功能:
1、设置请求的优先级,如果设置了优先级,服务器接收到请求之后,会优先处理优先级高的请求
2、服务器推送,可以直接将数据提前推送到浏览器
3、头部压缩,HTTP/2 对请求头和响应头进行了压缩
HTTP/3
HTTP/2 的缺陷
HTTP/2 虽然解决了一些问题,但依然有缺陷:
1、TCP 的队头阻塞
虽然 HTTP/2 解决了应用层面的队头阻塞问题,但它依然是基于 TCP 协议,多个请求仍然是跑在一个 TCP 管道中。如果在数据传输的过程中,有一个数据因为网络故障或者其他原因而丢包了,那么整个 TCP 的连接就会处于暂停状态,需要等待丢失的数据包被重新传输过来,这种由于单个数据包的丢失而造成的阻塞称为 TCP 上的队头阻塞。
2、TCP 建立连接的延时
从浏览器发送一个数据包到服务器,再从服务器返回数据包到浏览器的整个往返时间称为 RTT(Round Trip Time),又称为网络延迟,它是反映网络性能的一个重要指标。
建立 TCP 连接时需要三次握手,则至少要 1.5 个 RTT。如果是 HTTPS 的话,则还需要 TLS 握手,TLS 有 TLS1.2 和 TLS1.3 两个版本,大致是需要 1~2 个 RTT。
3、TCP 协议僵化
已知 TCP 协议有队头阻塞和建立连接延迟的缺点,理论上可以通过改进 TCP 协议来解决这些问题,但在实际操作上非常困难。造成 TCP 协议僵化的主要原因:
1)中间设备的僵化。各种中间设备一般在部署后就很少升级软件,如果客户端使用新协议,但中间设备并不理解就会造成数据丢失
2)操作系统更新滞后。TCP 协议一般都是操作系统内核来实现的,应用程序一般只能使用而不能修改,而操作系统通常都滞后于软件的更新
QUIC 协议
由于中间设备的僵化,设备只认 TCP 和 UDP。在既无法采用新协议,又无法改进 TCP 协议的情况下,HTTP/3 选择了一个折衷的方法——基于 UDP 实现了类似于 TCP 的多路数据流、传输可靠性等功能的 QUIC 协议。
QUIC 协议的功能:
1、实现了类似 TCP 的流量控制、传输可靠性的功能。
2、集成了 TLS 加密功能。使用 TLS1.3,减少了握手所花费的 RTT 个数。
3、实现了 HTTP/2 中的多路复用功能。QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流,使得数据流都是单独传输,这就解决了 TCP 中队头阻塞问题。
4、实现了快速握手功能,基于 UDP 协议使用 0-RTT 或者 1-RTT 就可以建立连接
但 HTTP/3 的应用也有诸多挑战:
1、支持度不好,服务器和浏览器的支持度都不够
2、部署也有问题,系统内核对 UDP 的优化远低于 TCP 的优化程度
3、中间设备僵化,设备对 UDP 的优化也远低于 TCP
状态码
1xx:指示信息–表示请求已接收,继续处理。
2xx:成功–表示请求已被成功接收、理解、接受。
3xx:重定向–要完成请求必须进行更进一步的操作。
4xx:客户端错误–请求有语法错误或请求无法实现。
5xx:服务器端错误–服务器未能实现合法的请求。
常见状态码
200 请求成功
204 处理成功,但无返回内容
301 永久移动
302 临时移动
304 文件未发生修改,不返回资源内容
400 错误请求,不理解请求的语法
401 未授权,需要身份验证
403 禁止,服务器拒绝请求
404 未找到请求的资源
500 服务器内部错误