HTTP 到底是干啥的?(万字解析)

本文已收录于专栏
⭐️ 《计算机网络》⭐️

HTTP

HTTP概述

HTTP 通常被译为超文本传输协议。

所谓的协议就是使用计算机能够理解的语言确立了一种计算机之间交流通信的规范,以及相关的各种控制和错误处理方式。

将译文拆开来解释就是:

HTTP 是一个在计算机世界里专门在两点(客户端和服务器端之间)之间 传输 文字、图片、音频、视频等超文本数据的约定和规范。

浏览器中输入URL后到底发生了什么?中我们知道,HTTP在这个过程中扮演者重要角色。

HTTP 协议用于客户端和服务器端之间的通信 。

请求访问文本或图像等资源的一端称为客户端,例如主机中的浏览器。

而提供资源响应的一端称为服务器端,例如web服务器。

HTTP通过请求和响应的交换达成通信。

HTTP 协议规定,请求从客户端发出,最后由服务端接收后返回响应。

也就是说先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。

如上图,客户端先向服务端发起一个请求报文,服务端在接收后会返回一个响应报文。

HTTP报文

用于 HTTP 协议交互的信息被称为 HTTP 报文。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p4wHMjcJ-1658845403586)(D:\Note\Computer network\image-20220726155712179.png)]

HTTP 协议的请求和响应报文中必定包含 HTTP 首部。

首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。

报文首部通常由几个字段构成。

请求报文

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存失败,源站可能有防盗链机制,建议将图片保存下来直接上传下上传(ihUVkUxgwdI5-1658845403587)(D:\Note\Computer network\image-20220726160539782.png)(D:\Note\Computer network\image-20220726160539782.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9PRq7OZu-1658845403588)(D:\Note\Computer network\image-20220726150140732.png)]

HTTP请求报文由请求行、首部字段、空行和请求体四个部分组成。

  • 请求行:包括请求方法,访问的资源URL,使用的HTTP版本。
    • GETPOST是最常见的HTTP方法,除此以外还包括DELETEHEADOPTIONSPUTTRACE
  • 首部字段:在报文众多的字段当中,HTTP 首部字段包含的信息最为丰富,服务端根据首部字段获取客户端的信息。
    • 主要有cookiehostconnectionaccept-languageaccept-encodinguser-agent
  • 请求体:用户的请求数据如用户名,密码等。
POST /xxx HTTP/1.1 请求行
Accept:image/gif.image/jpeg, 请求头部
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate

username=dabin 请求体响应报文

响应报文

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zTx0ycps-1658845403589)(D:\Note\Computer network\image-20220726160403609.png)]

HTTP响应报文由状态行、首部字段、空行和响应体四个部分组成。

状态行:协议版本,状态码(数字和原因短语)及状态描述。

首部字段:响应头字段主要有connectioncontent-typecontent-encodingcontent-lengthset-cookieLast-Modified,、Cache-ControlExpires

响应体:服务器返回给客户端的内容。

HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112

<html>
    <body>响应体</body>
</html>

定位资源的URL

HTTP 协议使用 URL 定位互联网上的资源。正是因为 URL 的特定功 能,在互联网上任意位置的资源都能访问到。

URL(统一资源定位符)是Internet上资源的地址,可以定义为引用地址的字符串,用于指示资源的位置以及用于访问它的协议。

其实通俗一点讲 URL 就是我们熟知的网址,其作用就是用于检索资源和资源名称。

  • 如果资源是Web类型资源,则URL在开头包含 http / https 。

  • 如果资源是电子邮件地址,则以 mailto 开头。

  • 如果资源是文件,则以 ftp 开头。

点击查看图片来源

如图所示,URL 包含了以下信息:

  • 用于访问资源的协议:如 httphttps
  • 服务器的位置,即网址域名:如 www.csdn.com
  • 服务器上的端口号: 这个是可以省略的。
  • 资源在服务器目录结构中的位置。

说到这里,其实 URL 还有一个 父亲 URI 可以聊聊。

URI(统一资源标识符)是标识逻辑或物理资源的字符序列,与URL类似,也是一串字符。通过使用位置,名称或两者来标识Internet上的资源;它允许统一识别资源。

有两种类型的URI,统一资源标识符(URL)和统一资源名称(URN

所以URLURI 的子集。

那URL和URI之间的主要区别是什么呢?

可以说URL是URI(URL是URI的子集),但URI永远不能是URL

  • URL(统一资源定位符)主要用于链接网页,网页组件或网页上的程序,借助访问方法(http,ftp,mailto等协议)来检索位置资源。
  • URI(统一资源标识符)用于定义项目的标识,此处单词标识符表示无论使用的方法 是什么(URL或URN),都要将一个资源与其他资源区分开来。
  • URL 指定要使用的协议类型,而URI不涉及协议规范。

返回结果的状态码

HTTP 状态码负责表示客户端 HTTP 请求的返回结果、标记服务器端

的处理是否正常、通知出现的错误等工作。

 五大类 HTTP 状态码

  • 1xx 类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。

    • 大概率不会碰到,所以这里直接跳过。
  • 2xx类状态码表示服务器成功处理了客户端的请求。

    • 200 OK:请求被成功处理,服务端返回的响应报文里有body数据。
    • 204 No Content: 请求被成功处理,但是没有返回任何内容。即服务端返回的响应报文里没有body数据。
    • 201 Create :请求被成功处理并且在服务端创建了一个新的资源。比如我们通过 POST 请求创建一个新的用户。
    • 202 Accepted :服务端已经接收到了请求,但是还未处理。
  • 3xx 类状态码表示客户端请求的资源发生了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向

    • 301 Moved Permanently : 资源被永久重定向了。比如你的网站的网址更换了。
    • 302 Found :表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。比如你的网站的某些资源被暂时转移到另外一个网址。
    • 304 Not Modified :不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制。
  • 4xx 类状态码表示客户端发送的报文有误,服务器无法处理,属于客户端的错误码。

    • 400 Bad Request : 发送的HTTP请求存在问题,但只是个笼统的错误。比如请求参数不合法、请求方法错误。
    • 401 Unauthorized : 未认证却请求需要认证之后才能访问的资源。
    • 403 Forbidden :服务器直接拒绝HTTP请求,不处理。一般用来针对非法请求。
    • 404 Not Found :表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。
    • 409 Conflict : 表示请求的资源与服务端当前的存状态在冲突,请求无法被处理。
  • 5xx 类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。

    • 500 Internal Server Error:与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
    • 501 Not Implemented:表示客户端请求的功能还不支持,类似’'敬请期待”的意思。
    • 502 Bad Gateway:通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
    • 503 Service Unavailable:表示服务器当前很忙,暂时无法响应客户端,类似“网络服务正忙,请稍后重试”的意思。

告知服务器意图的方法

GET :获取资源。

GET 方法用来请求访问已被 URI 识别的资源。指定的资源经服务器端解析后返回响应内容。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-697tM1e4-1658845403595)(D:\Note\Computer network\image-20220726162443197.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kSJpXHBn-1658845403595)(D:\Note\Computer network\image-20220726162848027.png)]

POST:传输实体主体 。

虽然用 GET 方法也可以传输实体的主体,但一般不用 GET 方法进行 传输,而是用 POST 方法。

虽说 POST 的功能与 GET 很相似,但 POST 的主要目的并不是获取响应的主体内容,而是传输实体的主体。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Js17jwvs-1658845403596)(D:\Note\Computer network\image-20220726162508717.png)]

PUT:传输文件 。

PUT 方法用来传输文件。就像 FTP 协议的文件上传一样,要求在请 求报文的主体中包含文件内容,然后保存到请求 URI 指定的位置。

但是,鉴于 HTTP/1.1 的 PUT 方法自身不带验证机制,任何人都可以 上传文件 , 存在安全性问题,因此一般的 Web 网站不使用该方法。若配合 Web 应用程序的验证机制或者架构设计采用REST标准的同类 Web 网站,就可能会开放使用 PUT 方法。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ONhoDIYw-1658845403597)(D:\Note\Computer network\image-20220726163246405.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aeQl8Yl7-1658845403598)(D:\Note\Computer network\image-20220726163328968.png)]

1 响应的意思其实是请求执行成功了,但无数据返回。

HEAD:获得报文首部 。

HEAD 方法和 GET 方法一样,只是不返回报文主体部分。用于确认 URI 的有效性及资源更新的日期时间等。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0HkXrXQN-1658845403598)(D:\Note\Computer network\image-20220726163427929.png)]

DELETE:删除文件 。

DELETE 方法用来删除文件,是与 PUT 相反的方法。DELETE 方法按 请求 URI 删除指定的资源。

但是,HTTP/1.1 的 DELETE 方法本身和 PUT 方法一样不带验证机制,所以一般的 Web 网站也不使用 DELETE 方法。当配合 Web 应用程序的验证机制,或遵守 REST 标准时还是有可能会开放使用的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p7IZ5q92-1658845403599)(D:\Note\Computer network\image-20220726163539443.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t6rvZDMB-1658845403600)(D:\Note\Computer network\image-20220726163614238.png)]

OPTIONS:询问支持的方法 。

OPTIONS 方法用来查询针对请求 URI 指定的资源支持的方法。

在这里插入图片描述

TRACE:追踪路径 。

TRACE 方法是让 Web 服务器端将之前的请求通信环回给客户端的方法。

客户端通过 TRACE 方法可以查询发送出去的请求是怎样被加工修改/ 篡改的。这是因为,请求想要连接到源目标服务器可能会通过代理中转,TRACE 方法就是用来确认连接过程中发生的一系列操作。

但是,TRACE 方法本来就不怎么常用,再加上它容易引发 XST(Cross-Site Tracing,跨站追踪)攻击,通常就更不会用到了。
[外链图片转议将图片保失败,源站可能有防盗链机制,建议中...(imgCsIWs3sB168899902726161207261.png403)(D:\Note\Computer network\image-220403)]

CONNECT:要求用隧道协议连接代理 。

CONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协 议进行 TCP 通信。主要使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输。

在这里插入图片描述

GET 和 POST 有什么区别?

GET 的语义是从服务器获取指定的资源,这个资源可以是静态的文本、页面、图片视频等。GET 请求的参数位置一般是写在 URL 中,URL 规定只能支持 ASCII,所以 GET 请求的参数只允许 ASCII 字符 ,而且浏览器会对 URL 的长度有限制(HTTP协议本身对 URL长度并没有做任何规定)

POST 的语义是根据请求负荷(报文body)对指定的资源做出处理,具体的处理方式视资源类型而不同。POST 请求携带数据的位置一般是写在报文 body 中, body 中的数据可以是任意格式的数据,只要客户端与服务端协商好即可,而且浏览器不会对 body 大小做限制。

GET 和 POST 方法都是安全和幂等的吗?

先说明下安全和幂等的概念:

  • 在 HTTP 协议里,所谓的「安全」是指请求方法不会「破坏」服务器上的资源。
  • 「幂等」,意思是多次执行相同的操作,结果都是「相同」的。

结论:

  • GET 方法是安全且幂等的,因为它是「只读」操作,无论操作多少次,服务器上的数据都是安全的,且每次的结果都是相同的。所以,可以对 GET 请求的数据做缓存,这个缓存可以做到浏览器本身上(彻底避免浏览器发请求),也可以做到代理上(如nginx),而且在浏览器中 GET 请求可以保存为书签

  • POST方法是不安全且不是幂等的 ,因为是「新增或提交数据」的操作,会修改服务器上的资源,所以是不安全的,且多次提交数据就会创建多个资源,所以不是幂等的。所以,浏览器一般不会缓存 POST 请求,也不能把 POST 请求保存为书签

传递重要信息的首部字段

HTTP 首部字段是构成 HTTP 报文的要素之一。在客户端与服务器之 以 HTTP 协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用。

使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容

HTTP 首部字段是由首部字段名和字段值构成的,中间用冒号“:” 分隔。

首部字段名: 字段值 

HTTP 首部字段根据实际用途被分为以下 4 种类型。

通用首部字段

请求报文和响应报文两方都会使用的首部。

常见的通用首部字段。

请求首部字段

从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加 内容、客户端信息、响应内容相关优先级等信息。

常见的请求首部字段。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zqwv7qFL-1658845403590)(D:\Note\Computer network\image-20220726161638311.png)]

响应首部字段

从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。

常见的响应首部字段。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UY4D3DSh-1658845403591)(D:\Note\Computer network\image-20220726161807887.png)]

实体首部字段

针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。

常见的实体首部字段。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5R1KmE3l-1658845403592)(D:\Note\Computer network\image-20220726161838399.png)]

下面详细介绍一下几个常见首部字段。

Host

客户端发送请求时, 会告知服务器,请求的资源所处的互联网主机名和端口号。
在这里插入图片描述

Host: www.A.com

有了 Host 字段,就可以将请求发往「同一台」服务器上的不同网站。

Connection

Connection 字段最常用于客户端要求服务器使用 TCP 持久连接,以便其他请求复用。

控制不再转发给代理的首部字段

HTTP/1.1 版本的默认连接都是持久连接,但为了兼容老版本的 HTTP,需要指定 Connection 首部字段的值为 Keep-Alive

Connection: keep-alive

Content-Length

服务器在返回数据时,会有 Content-Length 字段,表明本次回应的数据长度

**Content-Type **

Content-Type 字段用于服务器回应时,告诉客户端,本次数据是什么格式。

img
Content-Type: text/html; charset=utf-8

上面的类型表明,发送的是网页,而且编码是UTF-8。

客户端请求的时候,可以使用 Accept 字段声明自己可以接受哪些数据格式。

Accept: */*

上面代码中,客户端声明自己可以接受任何格式的数据。

Content-Encoding

Content-Encoding 字段说明数据的压缩方法。表示服务器返回的数据使用了什么压缩格式

img

Content-Encoding: gzip

上面表示服务器返回的数据采用了 gzip 方式压缩,告知客户端需要用此方式解压。

客户端在请求时,用 Accept-Encoding 字段说明自己可以接受哪些压缩方法。

Accept-Encoding: gzip, deflate

长连接和短连接

早期 HTTP/1.0 性能上的一个很大的问题,那就是每发起一个请求,都要新建一次 TCP 连接(三次握手),而且是串行请求,做了无谓的 TCP 连接建立和断开,增加了通信开销。

HTTP1.0 默认使用的是短连接

浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。

当客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源(如JavaScript文件、图像文件、CSS文件等),每遇到这样一个Web资源,浏览器就会重新建立一个HTTP会话。

为了解决上述 TCP 连接问题,HTTP/1.1 提出了长连接的通信方式,也叫持久连接。

这种方式的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。

HTTP长连接,指的是复用TCP连接。多个HTTP请求可以复用同一个TCP连接,这就节省了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。

HTTP/1.1 起默认使用长连接

在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭。

客户端再次访问这个服务器时,会继续使用这一条已经建立的连接。

Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。

当 HTTP 长连接超过一定时间没有任何数据交互,服务端就会主动断开这个连接。

实现长连接需要客户端和服务端都支持长连接。

保存资源的缓存

对于一些具有重复性的 HTTP 请求,比如每次请求得到的数据都一样的。

我们可以把这对「请求-响应」的数据都缓存在本地,那么下次就直接读取本地的数据。不必在通过网络获取服务器的响应了,这样的话 HTTP 的性能肯定肉眼可见的提升。

缓存服务器是代理服务器的一种,并归类在缓存代理类型中。

换句话说,当代理转发从服务器返回的响应时,代理服务器将会保存一份资源的副本。

即便缓存服务器内有缓存,也不能保证每次都会返回对同资源的请求。因为这关系到被缓存资源的有效性问题。

当遇上源服务器上的资源更新时,如果还是使用不变的缓存,那就会演变成返回更新前的“旧”资源了。

即使存在缓存,也会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。若判断缓存失效,缓存服务器将会再次从源服务器上获取“新”资源。

HTTP 缓存有两种实现方式,分别是强制缓存和协商缓存

强制缓存

强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。

分为三种情况:

  • 不存在该缓存结果和缓存标识,强制缓存失效,则直接向服务器发起请求。
  • 存在该缓存结果和缓存标识,但该结果已失效,强制缓存失效,则使用协商缓存。
  • 存在该缓存结果和缓存标识,且该结果尚未失效,强制缓存生效,直接返回该结果。

协商缓存

当我们在浏览器使用开发者工具的时候,你可能会看到过某些请求的响应码是 304,这个是告诉浏览器可以使用本地缓存的资源,通常这种通过服务端告知客户端是否可以使用缓存的方式被称为协商缓存。

协商缓存就是与服务端协商之后,判断本地缓存中的资源是否与服务器端的内容一致

服务器返回 304 状态码说明版本一致,浏览器可以直接读取本地缓存中的资源。

服务器返回 200 状态说明版本不一致,并将最新的资源给到浏览器。

Cookie和Session

HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管 理。也就是说,无法根据之前的状态进行本次的请求处理。

假设要求登录认证的 Web 页面本身无法进行状态的管理(不记录已 登录的状态),那么每次跳转新页面不是要再次登录,就是要在每次

请求报文中附加参数来管理登录状态。

无状态的好处,因为服务器不会去记忆 HTTP 的状态,所以不需要额外的资源来记录状态信息,这能减轻服务器的负担,能够把更多的 CPU 和内存用来对外提供服务。

无状态的坏处,既然服务器没有记忆能力,它在完成有关联性的操作时会非常麻烦。

保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了 Cookie 技术。

Cookie 原理

  • Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。

  • Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的 首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器 发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。

  • 服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。

HTTP 请求报文和响应报文的内容如下。

Session 原理

首先浏览器请求服务器访问 web 站点时,服务器首先会检查这个客户端请求是否已经包含了一个session标识、称为SESSION ID

如果已经包含了一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用.

如果客户端请求不包含session id,则服务器为此客户端创建一个session,并且生成一个与此session相关联的独一无二的session id存放到cookie中。

这个session id将在本次响应中返回到客户端保存,这样在交互的过程中,浏览器端每次请求时,都会带着这个session id,服务器根据这个session id就可以找得到对应的session。以此来达到共享数据的目的。 这里需要注意的是,session不会随着浏览器的关闭而死亡,而是等待超时时间。

Cookie和Session的区别?

  • 作用范围不同Cookie 保存在客户端,Session 保存在服务器端。
  • 有效期不同Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
  • 隐私策略不同Cookie 存储在客户端,容易被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
  • 存储大小不同, 单个 Cookie 保存的数据不能超过 4K;对于 `Session 来说存储没有上限,但出于对服务器的性能考虑,Session 内不要存放过多的数据,并且需要设置 Session 删除机制。

HTTP 2.0/3.0

HTTP2.0

HTTP2.0相比HTTP1.1支持的特性:

  • 新的二进制格式
    • HTTP1.1 基于文本格式 ASCII 编码传输数据;
    • HTTP2.0采用二进制格式传输数据,极大提高了 HTTP 传输效率,而且二进制数据使用位运算能高效解析。
  • 多路复用
    • HTTP/1.1 的实现是并发传输基于请求-响应模型的。
    • 同一个连接中,HTTP 1.0 完成一个事务(请求与响应),才能处理下一个事务。
    • 也就是说在发出请求等待响应的过程中,是没办法做其他事情的。
    • 如果响应迟迟不来,那么后续的请求是无法发送的,也造成了队头阻塞的问题。
    • 在一个连接里,允许同时发送多个请求或响应,并且这些请求或响应能够并行的传输而不被阻塞,避免 HTTP1.1 出现的”队头堵塞”问题。
  • 头部压缩
    • HTTP1.1的header带有大量信息,而且每次都要重复发送;
    • HTTP2.0 把header从数据中分离,并封装成头帧和数据帧,使用特定算法压缩头帧,有效减少头信息大小。
    • 并且HTTP2.0在客户端和服务器端记录了之前发送的键值对,对于相同的数据,不会重复发送。
    • 比如请求a发送了所有的头信息字段,请求b则只需要发送差异数据,这样可以减少冗余数据,降低开销。
  • 服务端推送
    • HTTP/1.1 不支持服务器主动推送资源给客户端,都是由客户端向服务器发起请求后,才能获取到服务器响应的资源。
    • HTTP2.0允许服务器向客户端推送资源,无需客户端发送请求到服务器获取。

HTTP3.0

HTTP/2 通过头部压缩、二进制编码、多路复用、服务器推送等新特性大幅度提升了 HTTP/1.1 的性能,而美中不足的是 HTTP/2 协议是基于 TCP 实现的,于是存在的缺陷有三个。

  • 队头阻塞;
    • HTTP/2 多个请求是跑在一个 TCP 连接中的,那么当 TCP 丢包时,整个 TCP 都要等待重传,那么就会阻塞该 TCP 连接中的所有请求。
  • TCP 与 TLS 的握手时延迟;
    • 发起 HTTP 请求时,需要经过 TCP 三次握手和 TLS 四次握手(TLS 1.2)的过程,因此共需要 3 个 RTT 的时延才能发出请求数据。
  • 网络迁移需要重新连接;
    • 一个 TCP 连接是由四元组(源 IP 地址,源端口,目标 IP 地址,目标端口)确定的,这意味着如果 IP 地址或者端口变动了,就会导致需要 TCP 与 TLS 重新握手,这不利于移动设备切换网络的场景,比如 4G 网络环境切换成 WIFI。

HTTP3.0做的改进

  • HTTP/3 将传输层从 TCP 替换成了 UDP,并在 UDP 协议上开发了 QUIC 协议,来保证数据的可靠传输。

  • 帧的结构相对简单,不需要在定义 Stream 直接使用QUIC里的 Stream ,帧头也只有两个字段:类型和长度。

  • HTTP/3 在头部压缩算法这一方便也做了升级,升级成了 QPACK。与 HTTP/2 中的 HPACK 编码方式相似,HTTP/3 中的 QPACK 也采用了静态表、动态表及 Huffman 编码。

QUIC

HTTP/3 不仅仅只是简单将传输协议替换成了 UDP,还基于 UDP 协议在「应用层」实现了 QUIC 协议,它具有类似 TCP 的连接管理、拥塞窗口、流量控制的网络特性,相当于将不可靠传输的 UDP 协议变成“可靠”的了,所以不用担心数据包丢失的问题。

QUIC 协议的优点:

  • 无队头阻塞。
    • QUIC 协议也有类似 HTTP/2 Stream 与多路复用的概念,也是可以在同一条连接上并发传输多个 Stream,Stream 可以认为就是一条 HTTP 请求。
    • 由于 QUIC 使用的传输协议是 UDP,UDP 不关心数据包的顺序,如果数据包丢失,UDP 也不关心。
    • 不过 QUIC 协议会保证数据包的可靠性,每个数据包都有一个序号唯一标识。
    • 当某个流中的一个数据包丢失了,即使该流的其他数据包到达了,数据也无法被 HTTP/3 读取,直到 QUIC 重传丢失的报文,数据才会交给 HTTP/3。
    • 而其他流的数据报文只要被完整接收,HTTP/3 就可以读取到数据。
    • 这与 HTTP/2 不同,HTTP/2 只要某个流中的数据包丢失了,其他流也会因此受影响。
    • 所以,QUIC 连接上的多个 Stream 之间并没有依赖,都是独立的,某个流发生丢包了,只会影响该流,其他流不受影响。
  • 更快的连接建立。
    • HTTP/3 在传输数据前虽然需要 QUIC 协议握手,这个握手过程只需要 1 RTT,握手的目的是为确认双方的「连接 ID」,连接迁移就是基于连接 ID 实现的。
  • 连接迁移。
    • QUIC 协议没有用四元组的方式来“绑定”连接,而是通过连接 ID来标记通信的两个端点。
    • 客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。

完结散花

ok以上就是对 的全部讲解啦,很感谢你能看到这儿。如果有遗漏、错误或者有更加通俗易懂的讲解,欢迎小伙伴私信我,我后期再补充完善。

参考文献

《图解HTTP》
https://www.xiaolincoding.com

猜你喜欢

转载自blog.csdn.net/m0_66139206/article/details/126004537