简述HTTP/1.x、HTTP/2.0、HTTP/3.0、HTTPS

488 阅读14分钟

HTTP/0.9

HTTP/0.9(HTTP/1.0之前的所有版本,统称为HTTP/0.9)非常简单:请求只有一行,并且只能进行GET请求,后面直接跟需要请求的html文件资源路径

GET /home.html

响应也同样只有一个HTML文档

<HTML>
    一个简单的HTML页面
</HTML>

HTTP/0.9因为不包HTTP头,所以只能请求HTML文件,不能传输其他文件;也没有状态码,当请求出现问题的时候,只能返回一个特殊的包含问题描述信息的HTML文件被返回。

HTTP/1.0

HTTP/0.9的极大局限性,自然无法满足人们的需要。于是便应运而生HTTP/1.0 相比之下,新增了以下内容:

  • 协议版本信息会跟随请求一起发送
  • 状态码会在相应开始的时候发送,使得浏览器能够知道请求成功或者失败,并以此来调整对应的行为(启用更新或者使用本地缓存文件)
  • 引入了HTTP头的概念,无论是请求还是相应,允许传输元数据,使协议变得非常灵活,更具有拓展性
  • 因为引入了新的HTTP,所以有了Conten-Type,使得HTTP除了传输其他类型文件的能力

HTTP/1.1

HTTP/1.1 在HTTP/1.0的基础上进行了多项改进

  • 连接复用

    HTTP协议是基于TCP/IP协议进行连接传输,在客户端与服务器的通信初始时,需要进行TCP的三次握手来建立传输通道,在数据传输完毕以后,还需要通过四次挥手来关闭连接。在HTTP/1.0中,每一次网络请求都需要建立TCP请求通道(即所谓的短链接),重复的建立连接和断开的过程,一方面耗时,另一方面浏览器对同一域名下的TCP连接数量存在限制,当网页上资源内容繁多的时候,加载就会非常缓慢。而在HTTP/1.1中,使用了长连接 Connection: keep-alive,在进行一次TCP连接请求后,TCP通道不会被立马关闭,后序请求可以直接复用该TCP连接通道。客户端会在最后一个请求时,发送Connection: close,明确要求服务器关闭TCP连接。

  • 管线机制、多路复用

    在HTTP/1.1 中引入了管道机制,即客户端通过同一个TCP连接可以同时发送多个请求,但是需要注意的是,虽然客户端请求同时发出,但是服务器依然会根据先后顺序来进行回应。而客户端在未收到之前发出的所有请求响应之前,将会阻塞后面的请求,即所谓的“对头阻塞”。

  • 支持响应分块 响应分块,及chunked分块技术:服务端将相应内容body体分成若干chunk快来分别来传输,表现为一边计算,一边传输。

    通常情况下,我们请求一个资源文件,比如图片的时候,服务端是能够准确的提高图片的大小,这是后我们可以在响应头中看到:Content-Length标识客户端需要接受多少的数据,服务端会将数据一次性返回。

    但是如果我们请求的是一个动态的内容,或者是一个大数据量表格,服务端无法预知内容的大小,该如何处理呢?Transfer-Encoding:chunked 分块传输编码技术就是为了解决这个问题。同时使用了分块传输以后,就不会在需要使用Content-Length字段了。服务端使用了分块传输以后,就会将内容通过多次返回的方式,逐步的返回到客户端。

  • Host头:在HTTP/1.1中认为每台服务器都绑定这一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名。但是随着虚拟主机的技术发展,在一台物理服务器上可以存在多个虚拟主机,并且他们共享一个IP。客户端可以通过HOST头来指明请求将要发送到的服务器和端口号。如果没有包含端口号,会自动使用被请i去服务器的默认端口(在HTTPS中使用443端口,在HTTP中使用80端口)。请求消息中如果没有HOST头域或超过一个HOST域都会报错(400 Bad Request)。用了HOST字段,就可以将请求发往同一台服务器上的不用网站。

  • 错误状态管理:

    HTTP/1.1新增了24个错误状态响应码,比如409 表示请求资源与资源当前状态发生冲突;410表示服务器上的某个资源被永久性删除等

  • 缓存问题

    缓存是面试中经常容易被问到的,后序将新开一篇来单独讲解。

HTTP/1.1 存在的相关问题

  1. HTTP/1.1中使用的流水线技术也只能部分处理请求并发,但是仍然会存在队列头阻塞问题,因此客户端再需要发起起多次请求时,通常会采用多连接来减少延迟
  2. 单向请求,当需要检测服务端发送的消息时,只有通过轮询请求,造成严重的性能问题
  3. 请求报文与响应报文首部信息冗余量大,每次请求和响应都会携带一大堆的请求头和响应头
  4. 数据未压缩,数据传输量大

HTTP/2.0

HTTP2.0 大幅度提高了web性能,再HTTP1.1完全语义兼容性的基础上,进一步减少了网络的延迟,低延迟高吞吐量,对于前端开发者而言,减少了开发优化功工作。 核心新特性:

  • 二进制分帧
  • 首部压缩
  • 多路复用
  • 请求优先级
  • 服务器推送

二进制分帧

什么是帧?

  • 帧: HTTP2.0通信的最小单位,所有的帧都共享着一个8字节的首部,其中包含有帧的长度、类型、标志还有一个保留位,并且至少有表示当前帧所属的流的标识符,帧承载着特定类型的数据,如HTTP首部等等。
  • 消息: 比帧大的通讯单位,是指逻辑上的HTTP消息,比如请求、响应等。由一个帧或者多个帧组成
  • 流: 比消息大的通讯单位。是TCP连接中的一个虚拟通道,可以承载双向的消息。每个流都有一个唯一的整数标识符

HTTP2.0中所有加强性能的核心是二进制传输,在HTTP1.x中,是通过文本的方式传输数据。基于文件的方式传输数据存在很多缺陷,文本的表现形式由多样性,所以要考虑各种兼容性的问题,而二进制则只有0和1的组合,使用二进制传输,实现方便并且健壮性好。

为了保证HTTP不受影响,那就需要在应用层(HTTP2.0)和传输层(TCP or UDP)之间加一个二进制分帧层。在二进制分帧层上,HTTP2.0会将所有的传输信息分为更小的消息和帧。并且采用二进制格式编码,其中HTTP1.x的首部信息会被封装到Header帧,而Request body 会被封装到Data帧中。

首部压缩

HTTP每次通讯(请求或者响应)都会携带首部信息用于描述资源属性。 在HTTP1.x中,使用文本的形式传输header,在header中携带cookie的话,每次都需要重复传输几百到几千的字节。

对于相同的数据,不需要每次请求和响应都发送,通信期间几乎不会改变通用键-值对。如果首部发生了变化,则只需要将变化的部分加入到header帧中,改变的部分会加入到头部字段表中,首部表在http2.0的连续存续期内始终存在,由客户端和服务器共同渐进更新

首部压缩原理

  • 客户端和服务器端共同维护一份静态表和一份动态表(用于记录首部的name和value。这两个结合起来充当字段的角色)
  • 每次请求时,发送方根据字典的内容以及特定指令,编码压缩消息头部
  • 接收方更具字典进行解码,并根据指令来判断是否需要更新动态表
  1. 静态表 静态表很简单,是指只包含已知的header字段。分为两种:
  • name和value都可以完全确定,比如method:GET, status: 200
  • 只能够确定name,比如: cooike、User-Agent等
  1. 动态表
  • 动态表最初是一个空表,当每次解压头部的时候,有可能会添加条目(比如前面提到的cooike,当解压过一次cookie, cookie:xxxx就会被自动添加到动态表中,至于是否添加需要根据指令来判断)
  • 动态表中允许包含重复的条目,也就是可能出现完全相同的键值对
  • 为了限制解码器的需求,动态表大小有严格的限制。

多路复用

在HTTP1.x中,需要经常使用到雪碧图、多个域名等方式来进行优化,因为浏览器对同一个域名下建立TCP的连接数量有限制(不同浏览器不同,一般是6到8个)当页面需要加载较多资源时,对头阻塞会导致在达到最大请求时,资源需要等待其他资源请求完以后才能继续发送。 HTTP2.0是基于二进制分帧层,在HTTP2.0可以在共享TCP连接的基础上同时发送请求和响应。HTTP消息被分解为独立的帧,而不破话消息本身的含义,交错发出去,在另一端根据流的标识符和首部将他们重新组装起来。

请求优先级

每个HTTP2.0流里面有个优先值,这个优先值确定着客户端和服务器处理不同的流采取不同的优先级策略,高优先级的流都应该优先发送,但又不会绝对的。绝对地准守,可能又会引入首队阻塞的问题:高优先级的请求慢导致阻塞其他资源交付。分配处理资源和客户端与服务器间的带宽,不同优先级的混合也是必须的。

HTTP2.0的服务器推送

HTTP 2.0 新增的一个强大的新功能,就是服务器可以对一个客户端请求发送多个响应。换句话说,服务器除了对最初请求的响应外,还可以额外向客户端推送资源,而无需客户端明确地请求。

有了HTTP2.0的服务器推送,HTTP1.x时代的内嵌资源的优化手段也变得没有意义了。而且使用服务器推送的资源的方式更加高效,因为客户端还可以缓存起来,甚至可以由不同的页面共享(依旧遵循同源策略)。当然,浏览器是可以拒绝服务器推送的资源。

HTTP/3.0

真正的下一代可靠的高速应用层通信技术

无论是HTTP/1.x还是HTTP/2.0都是基于TCP协议,众所周知,TCP连接和断开时时候,需要经历三次挥手、四次挥手的过程在多次建立链接的时候,自然就会影响传输速度。

QUIC

什么是QUIC协议呢?在我们熟悉的认知中,网络传输层的协议不外乎就是TCP和UDP协议,大家一致认为,TCP协议是面向有连接的,安全的。UDP协议是无连接的,不安全的。所以之前版本的各种HTTP协议都是基于TCP协议。但是正是因为TCP是面向连接的,需要经历三次握手,四次挥手阶段。所以就必然存在效率的问题。 而QUIC协议,正是用于解决这个问题。QUIC协议,也叫快速 UDP 互联网连接协议,从名字上可以看出,它是基于UDP协议而生。UDP协议最大的问题在于,客户端发出UDP数据包以后,只能假设这个数据包已经被服务器端接受,这样的好处是在网络传输层无需对数据包进行确认,但是存在的问题就是不能保证传输数据的可靠性。

QUIC的特点

1.QUIC协议可以在1到2个数据包内完成服务器和客户端的连接创建

2.对头阻塞和流量控制

在HTTP/1.1中实现了长连接,让多个域名下的请求复用同一连接,但是必须排队使用。当前一个请求一直无法完成的时候,势必会阻塞后面的请求。 在HTTP/2.0中实现了多路复用的机制,在一定程度上缓解了对头阻塞现象,同一链路上的请求不在依次等待,大家可以间隔进行。对于同一条链路上的请求,可以交错并行。但是这也没有完全解决阻塞问题。因为TCP的流量控制策略的本质没有改变。

  • TCP流量控制策略 TCP保证了数据的有序和可达性,所以数据按照序号依次发送和接收,下一个包的发送需要等到上一个ACK上一个包ACK到达。这样的话,在相邻两个包的发送间隙存在很长时间的空闲等待。但是TCP再用了滑动窗口机制来减少排队等待时间。双方约定一定大小的窗口,在这个窗口内的包都可以同步发送,接收者收到一个包时,会回复对应的ACK给发送者,发送者收到ACK后移动发送窗口,发送后续数据。但是如果某个包丢失或者对应的ACK丢失,同样会出现一放不必需要的等待。因为在同时传输多个包时,TCP层面是无法区分哪个包对应哪个请求的,所以当其中一个包丢失了,会导致后续已经被接收的包无法被应用层读取,请求阻塞。 QUCI协议的流量控制策略中较好的解决了这个问题。
  1. 拥塞控制

  2. 前向纠错&重传

  3. 链接迁移

感兴趣的朋友可以移步 www.mobibrw.com/2020/23190 查看具体的内容细节

HTTPS

HTTPS即HTTP+SSL/TLS,即在HTTP下加入SSL层,HTTPS的安全基础是SSL,加密的内容需要使用SSL,用于安全的HTTP数据传输。

简述HTTPS的握手过程

服务端发送自己的公钥到权威机构,机构根据服务端信息,利用自己的私钥加密生成签名信息,合并成一个证书,颁发到服务器。(这就是服务器证书的由来)

  • 具体连接过程 1、客户端发送连接请求,并且发送自己所支持的加密方式到服务器

2、服务端选择一个加密方式,然后将自己的证书以及选择的加密方式一起发送到客户端

3、客户端对证书的合法性进行校验,校验通过以后从本地操作系统中找到证书对应的公钥。

4、客户端利用证书公钥解密证书中被私钥加密的内容,得到服务端公钥

5、客户端利用服务端选择的加密方式,生成对应的加密的密钥,然后使用服务端的公钥对密钥进行加密

6、客户端发送该加密后的密钥到服务器

7、服务器通过自己的私钥解密内容,得到客户端的密钥

8、客户端和服务端通过密钥进行数据传输。

问题:

  • 什么是密钥? 密钥是加密算法中用于加密和解密一种算法。对称加密中加密和解密的密钥都是相同的,加解密算法比较简单,但是安全性较低。
  • 什么是私钥、公钥? 私钥和公钥是非对称加密用于加解密的密钥,非对称中加解密的密钥是不同的,分别成为公钥、私钥。公钥和算法都是公开的,私钥是保密的。非对称加密算法复杂性能低,但是安全性超强。
  • 为什么不直接使用对称加密进行数据传输 因为对称加密算法比较简单,在客户端与服务器的过程中,可能传输信息会被中间人拦截,中间人拦截到了传输信息,拿到了密钥以后,就可以伪造信息在服务端和客户端之间进行数据传输。
  • 为什么不直接使用非对称加密传输 因为非对称加密算法复杂度高,加密性能复杂,并且能够加密的字段长度有限,所以不能够直接使用非对称加密进行数据传输。