浏览器/浏览器中的网络

122 阅读10分钟

http/0.9

产生背景(需求)

主要用于学术交流,需求很简单——用来在网络之间传递 HTML 超文本的内容

请求流程

image.png

特点

  1. 第一个是只有一个请求行,并没有 HTTP 请求头和请求体,因为只需要一个请求行就可以完整表达客户端的需求了。
  2. 第二个是服务器也没有返回头信息,这是因为服务器端并不需要告诉客户端太多信息,只需要返回数据就可以了。
  3. 第三个是返回的文件内容是以 ASCII 字符流来传输的,因为都是 HTML 格式的文件,所以使用 ASCII 字节码来传输是最合适的。

http/1.0

产生背景(需求)

万维网的高速发展带来了很多新的需求,在浏览器中展示的不单是 HTML 文件了,还包括了 JavaScript、CSS、图片、音频、视频等不同类型的文件,而且文件格式不仅仅局限于 ASCII 编码,还有很多其他类型编码的文件

解决方案(解决需求)

http1.0在http0.9的基础上,在请求中增加了请求头、响应头。

工作流程如下:

  1. 首先,浏览器需要知道服务器返回的数据是什么类型的,然后浏览器才能根据不同的数据类型做针对性的处理。
  2. 其次,由于万维网所支持的应用变得越来越广,所以单个文件的数据量也变得越来越大。为了减轻传输性能,服务器会对数据进行压缩后再传输,所以浏览器需要知道服务器压缩的方法。
  3. 再次,由于万维网是支持全球范围的,所以需要提供国际化的支持,服务器需要对不同的地区提供不同的语言版本,这就需要浏览器告诉服务器它想要什么语言版本的页面。
  4. 最后,由于增加了各种不同类型的文件,而每种文件的编码形式又可能不一样,为了能够准确地读取文件,浏览器需要知道文件的编码类型
请求头
accept: text/html // 数据类型
accept-encoding: gzip, deflate, br // 压缩方法
accept-Charset: ISO-8859-1,utf-8 // 文件的编码类型
accept-language: zh-CN,zh // 语言版本

响应头,最终浏览器需要根据响应头的信息来处理数据
content-encoding: br
content-type: text/html; charset=UTF-8

功能优化

  1. 有的请求服务器可能无法处理,或者处理出错,这时候就需要告诉浏览器服务器最终处理该请求的情况,这就引入了状态码
  2. 状态码是通过响应行的方式来通知浏览器的。为了减轻服务器的压力,在 HTTP/1.0 中提供了 Cache 机制,用来缓存已经下载过的数据。
  3. 服务器需要统计客户端的基础信息,比如 Windows 和 macOS 的用户数量分别是多少,所以 HTTP/1.0 的请求头中还加入了用户代理的字段。

请求流程

image.png

http/1.1

产生背景(需求)

  1. HTTP/1.0 每进行一次 HTTP 通信,都需要经历建立 TCP 连接、传输 HTTP 数据和断开 TCP 连接三个阶段.有时候一个页面可能包含了几百个外部引用的资源文件,如果在下载每个文件的时候,都需要经历建立 TCP 连接、传输数据和断开连接这样的步骤,无疑会增加大量无谓的开销。
  2. 在 HTTP/1.0 中,每个域名绑定了一个唯一的 IP 地址,因此一个服务器只能支持一个域名。但是随着虚拟主机技术的发展,需要实现在一台物理主机上绑定多个虚拟主机,虽然每个虚拟主机都有自己的单独的域名,但是这些单独的域名都公用同一个 IP 地址。
  3. 在设计 HTTP/1.0 时,需要在响应头中设置完整的数据大小,如Content-Length: 901,这样浏览器就可以根据设置的数据大小来接收数据。不过随着服务器端的技术发展,很多页面的内容都是动态生成的,因此在传输数据之前并不知道最终的数据大小,这就导致了浏览器不知道何时会接收完所有的文件数据。

解决方案(解决需求)

  1. HTTP/1.1 中增加了持久连接的方法,它的特点是在一个 TCP 连接上可以传输多个 HTTP 请求,只要浏览器或者服务器没有明确断开连接,那么该 TCP 连接会一直保持。浏览器中对于同一个域名,默认允许同时建立 6 个 TCP 持久连接。
  2. HTTP/1.1 的请求头中增加了 Host 字段,用来表示当前的域名地址,这样服务器就可以根据不同的 Host 值做不同的处理。
  3. HTTP/1.1 通过引入 Chunk transfer 机制来解决内容动态变化的问题,服务器会将数据分割成若干个任意大小的数据块,每个数据块发送时会附上上个数据块的长度,最后使用一个零长度的块作为发送数据完成的标志。这样就提供了对动态内容的支持。

http/2.0

产生背景

HTTP/1.1对带宽的利用率却并不理想,比如我们常说的 100M 带宽,实际的下载速度能达到 12.5M/S,而采用 HTTP/1.1 时,也许在加载页面资源时最大只能使用到 2.5M/S,很难将 12.5M 全部用满。原因如下:

  1. tcp的慢启动。一旦一个 TCP 连接建立之后,就进入了发送数据状态,刚开始 TCP 协议会采用一个非常慢的速度去发送数据,然后慢慢加快发送数据的速度,直到发送数据的速度达到一个理想状态,我们把这个过程称为慢启动。慢启动是 TCP 为了减少网络拥塞的一种策略,我们是没有办法改变的。
  2. 同时开启了多条 TCP 连接,那么这些连接会竞争固定的带宽。在下载过程中,当发现带宽不足的时候,各个 TCP 连接就需要动态减慢接收数据的速度。这样就会出现一个问题,因为有的 TCP 连接下载的是一些关键资源,但是多条 TCP 连接之间又不能协商让哪些关键资源优先下载,这样就有可能影响那些关键资源的下载速度了。
  3. HTTP/1.1 队头阻塞的问题。在 HTTP/1.1 中使用持久连接时,虽然能公用一个 TCP 管道,但是在一个管道中同一时刻只能处理一个请求,在当前的请求没有结束之前,其他的请求只能处于阻塞状态。

解决方案(解决需求)

HTTP/2 的解决方案可以总结为:一个域名只使用一个 TCP 长连接和消除队头阻塞问题(多路复用机制)。

image.png 从图中你会发现每个请求都有一个对应的 ID,如 stream1 表示 index.html 的请求,stream2 表示 foo.css 的请求。服务器端接收到这些请求后,会根据自己的喜好来决定优先返回哪些内容,比如服务器可能早就缓存好了 index.html 和 bar.js 的响应头信息,那么当接收到请求的时候就可以立即把 index.html 和 bar.js 的响应头信息返回给浏览器,然后再将 index.html 和 bar.js 的响应体数据返回给浏览器。之所以可以随意发送,是因为每份数据都有对应的 ID,浏览器接收到之后,会筛选出相同 ID 的内容,将其拼接为完整的 HTTP 响应数据。注意看图中深黄色部分,这些深黄色的方块其实是数据帧。http2.0将请求分成一帧一帧的数据去传输(就是这一步规避掉了http队头阻塞问题,浏览器根据id来组装请求即可),当收到一个优先级高的请求时,服务器可以暂停之前的请求来优先处理关键资源的请求。


功能优化

  1. 可以设置请求的优先级。HTTP/2 提供了请求优先级,可以在发送请求时,标上该请求的优先级,这样服务器接收到请求之后,会优先处理优先级高的请求。
  2. 服务器推送,言简意赅就是一个请求后,返回了额外的数据,这些额外的数据(由服务端决定)
  3. 头部压缩,http/1.0 只是提供了请求数据的压缩,但是没有对请求头和响应进行压缩,http/2.0则可以对请求头和请求行进行压缩。

详解多路复用

image.png

从图中可以看出,HTTP/2 添加了一个二进制分帧层,那我们就结合图来分析下 HTTP/2 的请求和接收过程。

  1. 首先,浏览器准备好请求数据,包括了请求行、请求头等信息,如果是 POST 方法,那么还要有请求体。
  2. 这些数据经过二进制分帧层处理之后,会被转换为一个个带有请求 ID 编号的帧,通过协议栈将这些帧发送给服务器。
  3. 服务器接收到所有帧之后,会将所有相同 ID 的帧合并为一条完整的请求信息。
  4. 然后服务器处理该条请求,并将处理的响应行、响应头和响应体分别发送至二进制分帧层。
  5. 同样,二进制分帧层会将这些响应数据转换为一个个带有请求 ID 编号的帧,经过协议栈发送给浏览器。
  6. 浏览器接收到响应帧之后,会根据 ID 编号将帧的数据提交给对应的请求。 从上面的流程可以看出,通过引入二进制分帧层,就实现了 HTTP 的多路复用技术。

http/3.0

产生背景

  1. tcp连接存在队头阻塞问题。和 HTTP/1.1 一样,HTTP/2 依然是基于 TCP 协议的,而 TCP 最初就是为了单连接而设计的。你可以把 TCP 连接看成是两台计算机之前的一个虚拟管道,计算机的一端将要传输的数据按照顺序放入管道,最终数据会以相同的顺序出现在管道的另外一头。如果在数据传输的过程中,有一个数据因为网络故障或者其他原因而丢包了,那么整个 TCP 的连接就会处于暂停状态,需要等待丢失的数据包被重新传输过来

http/1.1数据包传输过程

image.png

http/2.0数据包传输过程

image.png 2. TCP建立连接延时。 3. TCP 协议僵化,老物理设备没有条件改进tcp协议来解决tcp建立连接延时问题。

解决方案(解决需求)

基于 UDP 实现了类似于 TCP 的多路数据流、传输可靠性等功能,我们把这套功能称为 QUIC 协议。

  1. 实现了类似 TCP 的流量控制、传输可靠性的功能。
  2. 集成了 TLS 加密功能。
  3. 实现了 HTTP/2 中的多路复用功能。