HTTP协议浅识

150 阅读34分钟

HTTP协议浅识

HTTP背景知识

从在浏览器中输入url到网页呈现,这中间发生了什么?

如图:

  1. URL 解析:浏览器会解析您输入的 URL,提取出协议(例如 HTTP、HTTPS)、域名(例如 www.example.com)和路径等信息。
  2. DNS 解析:浏览器需要将域名解析为 IP 地址,以便与服务器建立连接。浏览器会发送 DNS 请求到本地 DNS 缓存或者 DNS 服务器,获取域名对应的 IP 地址。
  3. 建立 TCP 连接:使用解析得到的 IP 地址,浏览器会与服务器建立 TCP 连接。TCP 是一种可靠的传输协议,用于在网络上建立可靠的连接。
  4. 发起 HTTP 请求:一旦建立了 TCP 连接,浏览器会发送一个 HTTP 请求到服务器。这个请求包含了请求的方法(例如 GET、POST)、路径、请求头和请求体等信息。
  5. 服务器处理请求:服务器接收到浏览器发送的 HTTP 请求后,会根据请求的路径和其他信息来处理请求。服务器可能会执行一些后端逻辑,如查询数据库、处理文件等。
  6. 响应生成:服务器处理完请求后,会生成一个 HTTP 响应。响应包括状态码(例如 200 表示成功,404 表示未找到等)、响应头和响应体等信息。
  7. 响应传输:服务器生成的响应会通过建立的 TCP 连接传输回浏览器。TCP 协议会确保数据的可靠传输,如果数据包有丢失或损坏,TCP 会自动进行重传。
  8. 浏览器解析响应:浏览器接收到响应后,会解析响应的数据。浏览器会根据响应头中的内容类型(Content-Type)来确定如何解析响应体的数据,例如是 HTML、CSS、JavaScript 或者其他类型的数据。
  9. 网页渲染:一旦浏览器解析完响应的数据,它会将解析得到的 HTML 文档进行渲染,构建 DOM(文档对象模型)树,并加载和执行其中的 CSS 和 JavaScript 代码。
  10. 网页呈现:最后,浏览器根据渲染得到的 DOM 树和 CSS 样式对页面进行布局和绘制,将网页内容显示给用户。

计算机网络的分层模型 有 OSI七层参考模型TCP/IP四层参考模型,今天主要探索应用层中的HTTP协议

image-20230805234321759


HTTP概念解读

HTTP(Hypertext Transfer Protocol 超文本传输协议)是一种用于在网络上传输超文本的应用层协议。它是一种无状态的、无连接的协议,由客户端和服务器之间的请求和响应组成。

应用层协议,基于TCP协议

TCP(Transmission Control Protocol)是一种可靠的传输协议,它提供了面向连接的、可靠的数据传输。HTTP利用TCP协议的可靠性来确保数据的完整性和正确性。

在HTTP通信中,客户端和服务器之间首先建立TCP连接。TCP通过三次握手的方式建立连接,确保通信双方都能够正常收发数据。一旦建立了TCP连接,HTTP请求和响应的数据就可以通过这个连接进行可靠的传输。

image-20230805234648289

请求&响应

在HTTP协议中,通信的基本单位是请求(Request)和响应(Response)。

请求(Request)是客户端向服务器发送的消息,用于请求服务器执行某个动作或获取某个资源。一个HTTP请求通常包括以下部分:

  1. 请求行(Request Line):包含请求方法、URL和HTTP协议版本。常见的请求方法有GET、POST、PUT、DELETE等。

  2. 请求头(Request Headers):包含一些附加的信息,如用户代理(User-Agent)、请求的内容类型(Content-Type)、请求的语言(Accept-Language)等。

  3. 请求体(Request Body):可选的,用于传输一些数据,如在POST请求中发送表单数据或上传文件时使用。

    image-20230805235416534

响应(Response)是服务器对客户端请求的回应,包含了请求的结果和一些附加信息。一个HTTP响应通常包括以下部分:

  1. 状态行(Status Line):包含响应的状态码和状态消息。常见的状态码有200表示成功,404表示未找到,500表示服务器内部错误等。

  2. 响应头(Response Headers):包含一些附加的信息,如服务器类型(Server)、响应的内容类型(Content-Type)、响应的长度(Content-Length)等。

  3. 响应体(Response Body):实际的响应数据,可以是HTML文档、JSON数据、图片等。

    image-20230805235615948

客户端发送一个请求到服务器,服务器接收到请求后进行处理,并生成一个响应发送回客户端。客户端接收到响应后,解析响应的数据并进行相应的处理,如渲染网页、处理数据等。

通过请求和响应的交互,客户端和服务器之间可以进行数据的传输和交互,实现了Web应用的功能和交互。

简单可拓展

  1. 请求方法(Request Methods):HTTP定义了一些常见的请求方法,如GET、POST、PUT、DELETE等。但它也允许扩展新的请求方法,以满足特定的需求。例如,WebDAV扩展了HTTP协议,添加了一些用于文件管理的请求方法,如PROPFIND、MKCOL等。
  2. 头部字段(Headers):HTTP的头部字段是以键值对的形式传递附加信息的。它允许用户自定义的头部字段,以便传递特定的信息。这使得开发人员可以根据需要添加自定义的头部字段,以实现额外的功能或传递特定的参数。
  3. 媒体类型(Media Types):HTTP使用Content-Type头部字段来指定传输的媒体类型,如text/html、application/json等。它允许自定义的媒体类型,以支持新的数据格式或协议。例如,application/vnd.api+json是一种自定义的媒体类型,用于表示JSON格式的API数据。
  4. 扩展头部(Extension Headers):HTTP/2引入了扩展头部的概念,允许开发人员定义自己的头部字段,并在通信中使用。这样可以在不影响协议本身的情况下,通过扩展头部实现额外的功能或传递自定义的信息。

无状态

HTTP协议被称为无状态协议(Stateless Protocol),这意味着服务器在处理每个请求时不会保留任何关于客户端的状态信息。

无状态的特性使得服务器不需要维护客户端的状态信息,从而提高了服务器的可伸缩性和可靠性。每个请求都是独立的,服务器只需根据请求的内容进行处理,并发送相应的响应,而无需考虑之前的请求或客户端的状态。

由于HTTP协议的无状态性质,服务器无法直接识别不同的客户端或跟踪用户的会话。为了实现用户会话管理和状态跟踪,通常使用一些机制,如使用Cookie、Session等技术。

使用Cookie,服务器可以在响应中设置一个唯一的标识符,称为Cookie,然后在后续的请求中,客户端会自动将该Cookie包含在请求中,从而实现了对用户的识别和状态跟踪。

使用Session,服务器会为每个用户创建一个唯一的会话标识符,并将该标识符存储在服务器端的存储介质中,如内存或数据库中。然后,服务器在响应中将该会话标识符发送给客户端,在后续的请求中,客户端会将该会话标识符包含在请求中,以便服务器可以识别用户并恢复相关的会话数据。

通过这些机制,服务器可以在无状态的HTTP协议上实现状态管理和用户会话跟踪,从而实现更复杂的应用功能和交互。

无连接

无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

早期这么做的原因是 HTTP 协议产生于互联网,因此服务器需要处理同时面向全世界数十万、上百万客户端的网页访问,但每个客户端(即浏览器)与服务器之间交换数据的间歇性较大(即传输具有突发性、瞬时性),并且网页浏览的联想性、发散性导致两次传送的数据关联性很低,大部分通道实际上会很空闲、无端占用资源。因此 HTTP 的设计者有意利用这种特点将协议设计为请求时建连接、请求完释放连接,以尽快将资源释放出来服务其他客户端

随着时间的推移,网页变得越来越复杂,里面可能嵌入了很多图片,这时候每次访问图片都需要建立一次 TCP 连接就显得很低效。后来,Keep-Alive 被提出用来解决这效率低的问题。

Keep-Alive 功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive 功能避免了建立或者重新建立连接。市场上的大部分 Web 服务器,包括 iPlanet、IIS 和 Apache,都支持 HTTP Keep-Alive。对于提供静态内容的网站来说,这个功能通常很有用。但是,对于负担较重的网站来说,这里存在另外一个问题:虽然为客户保留打开的连接有一定的好处,但它同样影响了性能,因为在处理暂停期间,本来可以释放的资源仍旧被占用。当Web服务器和应用服务器在同一台机器上运行时,Keep-Alive 功能对资源利用的影响尤其突出。

这样一来,客户端和服务器之间的 HTTP 连接就会被保持,不会断开(超过 Keep-Alive 规定的时间,意外断电等情况除外),当客户端发送另外一个请求时,就使用这条已经建立的连接。


HTTP协议特征

发展历程

image.png

  1. HTTP/0.9:这是最早的版本,也是最简单的版本。它只支持GET方法,用于获取HTML文档,并没有定义头部字段等其他功能。
  2. HTTP/1.0:在1996年发布,这是第一个被广泛采用的HTTP版本。它引入了多种请求方法(如GET、POST、HEAD等)和响应状态码(如200 OK、404 Not Found等),以及头部字段的概念。HTTP/1.0使用短连接,即每个请求/响应都需要建立和关闭一个新的连接。
  3. HTTP/1.1:在1999年发布,HTTP/1.1是目前最广泛使用的HTTP版本。它引入了持久连接(Keep-Alive)的概念,使得多个请求/响应可以通过同一个连接进行传输,减少了连接建立和关闭的开销。HTTP/1.1还引入了管道化(Pipelining)机制,允许客户端在同一个连接上发送多个请求,而无需等待每个响应。此外,HTTP/1.1还引入了一些性能优化的特性,如缓存控制、分块传输编码等。
  4. HTTP/2:在2015年发布,HTTP/2是对HTTP/1.1的重大改进。它基于Google的SPDY协议,并引入了二进制分帧层,通过多路复用技术在单个连接上同时传输多个请求和响应。HTTP/2还支持服务器推送(Server Push),允许服务器在客户端请求之前主动推送相关的资源。这些改进使得HTTP/2更高效、更快速,并提供更好的性能。
  5. HTTP/3:在2020年发布,HTTP/3是基于QUIC协议的新一代HTTP协议。它使用UDP协议而不是TCP协议作为传输层协议,以解决TCP的一些性能问题。HTTP/3保留了HTTP/2的特性,并引入了一些新的改进,如0-RTT连接建立、连接迁移等,以提供更快的连接建立和更可靠的传输。

报文

在HTTP协议中,通信的基本单位是HTTP报文。HTTP报文分为请求报文和响应报文两种类型。

image-20230806001848530

  1. 请求报文(Request Message):由客户端发送给服务器,用于请求服务器执行某个操作或获取某个资源。请求报文包括以下几个部分:

    • 请求行(Request Line):包含请求方法、请求目标(URL或URI)和HTTP协议版本。
    • 请求头部(Request Headers):包含关于请求的附加信息,如Host、User-Agent、Content-Type等。
    • 空行(Blank Line):用于分隔请求头部和请求体。
    • 请求体(Request Body):可选的,用于传输请求的数据,如POST请求中的表单数据或上传的文件内容。
  2. 响应报文(Response Message):由服务器发送给客户端,用于回应客户端的请求。响应报文包括以下几个部分:

    • 状态行(Status Line):包含HTTP协议版本、状态码和状态消息。
    • 响应头部(Response Headers):包含关于响应的附加信息,如Content-Type、Content-Length等。
    • 空行(Blank Line):用于分隔响应头部和响应体。
    • 响应体(Response Body):可选的,用于传输响应的数据,如HTML文档、JSON数据等。

请求报文和响应报文的结构类似,但在具体内容上有所区别。它们通过HTTP协议进行传输,客户端发送请求报文到服务器,服务器接收并处理请求,然后发送响应报文回到客户端。

HTTP报文的结构简单且灵活,允许在请求头部和响应头部中添加自定义的字段,以满足特定应用的需求。这种可拓展性是HTTP协议的一个重要特点,使得HTTP能够适应各种不同的应用场景和需求。

Method

方法名描述
GET请求一个指定资源的表示形式. 使用GET的请求应该只被用于获取数据
POST用于将实体提交到指定的资源,通常导致在服务器上的状态变化或副作用
PUT用请求有效载荷替换目标资源的所有当前表示
DELETE删除指定的资源
HEAD请求一个与GET请求的响应相同的响应,但没有响应体
CONNECT建立一个到由目标资源标识的服务器的隧道
OPTIONS用于描述目标资源的通信选项
TRACE沿着到目标资源的路径执行一个消息环回测试
PATCH用于对资源应用部分修改

分类

  1. 安全(Safe)方法:安全方法是指在执行请求时不会对服务器产生副作用,即不会修改服务器上的资源状态。安全方法只用于获取资源的操作,而不会对资源进行修改。常见的安全方法包括:

    • GET:用于获取资源的表示,不会对服务器状态进行修改,只是获取资源的信息。
    • HEAD:类似于GET方法,但只请求获取资源的头部信息,不返回实体主体。
    • OPTIONS:用于获取目标资源所支持的通信选项,不会对资源进行修改。

    安全方法可以在不担心对服务器产生影响的情况下进行重试或缓存,因为它们不会改变服务器的状态。

  2. 幂等(Idempotent)方法:幂等方法是指对同一资源重复执行相同的请求操作,结果也应该是相同的。即使对同一请求进行多次重复发送,服务器的状态也不会发生变化。常见的幂等方法包括:

    • GET:由于只是获取资源的表示,多次执行不会对服务器状态产生影响。
    • PUT:用于替换指定位置的资源,多次执行相同的PUT请求会得到相同的结果。
    • DELETE:用于删除指定的资源,多次执行相同的DELETE请求会得到相同的结果。

    幂等方法的特性使得在网络通信中出现问题时,可以安全地重试请求,而不会对服务器状态产生副作用。

需要注意的是,POST方法通常不被视为安全或幂等的方法,因为POST请求的语义是向服务器提交数据并可能对服务器状态产生影响。但是,可以通过在POST请求中使用适当的机制(如幂等标识符)来实现部分幂等性。

状态码

1xx(Informational,信息性状态码):表示请求已被接收,服务器正在处理请求的中间状态。

  • 100 Continue:服务器已接收到请求的起始部分,客户端应继续发送请求的剩余部分。
  • 101 Switching Protocols:服务器已理解客户端的请求,并将切换到不同的协议进行通信。

2xx(Success,成功状态码):表示请求已成功被服务器接收、理解和处理。

  • 200 OK:请求成功,服务器返回请求的内容。
  • 201 Created:请求成功,服务器创建了新的资源。
  • 204 No Content:请求成功,服务器处理成功,但没有返回任何内容。

3xx(Redirection,重定向状态码):表示客户端需要采取进一步的操作才能完成请求。

  • 301 Moved Permanently:请求的资源已永久移动到新位置。
  • 302 Found:请求的资源临时移动到不同的位置。
  • 304 Not Modified:客户端缓存的资源未过期,可以直接使用缓存的版本。

4xx(Client Error,客户端错误状态码):表示客户端发送的请求有错误。

  • 400 Bad Request:请求无效,服务器无法理解。
  • 401 Unauthorized:请求要求身份验证。
  • 404 Not Found:请求的资源不存在。

5xx(Server Error,服务器错误状态码):表示服务器在处理请求时发生错误。

  • 500 Internal Server Error:服务器内部错误,无法完成请求。
  • 503 Service Unavailable:服务器暂时无法处理请求,通常是由于过载或维护。
  • 504 Gateway Timeout:网关或者代理的服务器无法在规定的时间内获得想要的响应。

RESTful API

一种API设计风格;REST - Representational State Transfer

  1. 每一个URI代表一种资源;
  2. 客户端和服务器之间,传递这种资源的某种表现层;
  3. 客户端通过HTTP method,对服务器端资源进行操作,实现"表现层状态转化"。
请求返回码含义
GET /zoos200 OK列出所有动物园,服务器成功返回了
POST /zoos201 CREATED新建一个动物园,服务器创建成功
PUT /zoos/ID400 INVALID REQUEST更新某个指定动物园的信息(提供该动物园的全部信息)用户发出的请求有错误,服务器没有进行新建或修改数据的操作
DELETE /zoos/ID204 NO CONTENT删除某个动物园,删除数据成功
  • 传统API:把每个URL当作一个功能
  • Restful API: 把每个URL当作一个唯一的资源

用 URL 定位资源,用 HTTP 动词(GET,POST,DELETE,PUT)描述操作,尽量不用URL参数,用method表示操作类型

  1. url参数

    • 传统API :/api/list?pageIndex=2
    • Restful API :/api/list/2
  2. method表示操作类型

    • 传统API

      • POST请求 /api/create-blog
      • POST请求 /api/update-blog?id=100
      • GET请求 /api/get-blog?id=100
    • Restful API

      • POST请求 /api/blog
      • PATCH请求 /api/blog/100
      • GET请求 /api/blog/100

请求头

请求头(Request Header)是HTTP请求中的一部分,它包含了客户端向服务器发送请求时的相关信息和元数据。请求头通常以键值对的形式组织,每个键值对表示一个请求头字段和对应的值。

请求头说明
Accept接收类型,表示浏览器支持的MIME类型(对标服务端返回的Content-Type)
Content-Type客户端发送出去实体内容的类型
Cache-Control指定请求和响应遵循的缓存机制,如no-cache
If-Modified-Since对应服务端的Last-Modified,用来匹配看文件是否变动,只能精确到1s之内
Expires缓存控制,在这个时间内不会请求,直接使用缓存,服务端时间
Max-age代表资源在本地缓存多少秒,有效时间内不会请求,而是使用缓存
If-None-Match对应服务端的ETag,用来匹配文件内容是否改变(非常精确)
Cookie有cookie并且同域访问时会自动带上
Referer该页面的来源URL(适用于所有类型的请求,会精确到详细页面地址,csrf拦截常用到这个字段)
Origin最初的请求是从哪里发起的(只会精确到端口),Origin比Referer更尊重隐私
User-Agent用户客户端的一些必要信息,如UA头部等

响应头

响应头说明
Content-Type服务端返回的实体内容的类型
Cache-Control指定请求和响应遵循的缓存机制,如no-cache
Last-Modified请求资源的最后修改时间
Expires应该在什么时候认为文档已经过期,从而不再缓存它
Max-age客户端的本地资源应该缓存多少秒,开启了Cache-Control后有效
ETag资源的特定版本的标识符,Etags类似于指纹
Set-Cookie设置和页面关联的cookie,服务器通过这个头部把cookie传给客户端
Server服务器的一些相关信息
Access-Control-Allow-Origin服务器端允许的请求Origin头部(譬如为*)

缓存

image-20230806003524989

强缓存和协商缓存是HTTP缓存机制中的两种策略,用于控制客户端是否使用缓存的数据。

  1. 强缓存(Strong Caching):强缓存是通过在响应头中设置缓存相关字段来指示客户端可以直接使用缓存的数据,而无需向服务器发送请求。常见的强缓存字段有:

    • Cache-Control:通过设置Cache-Control字段,可以指定缓存的行为。常见的指令包括:

      • public:表示响应可以被任何缓存(包括客户端和代理服务器)缓存。
      • private:表示响应只能被客户端缓存,不能被代理服务器缓存。
      • max-age:指定缓存的有效期,以秒为单位。
      • s-maxage:类似于max-age,但仅适用于代理服务器缓存。
      • no-cache:表示缓存数据需要经过协商缓存验证后才能使用,不能直接使用强缓存。
      • no-store:表示不缓存响应的任何部分,每次请求都需要向服务器发送请求获取最新的数据。
    • Expires:通过设置Expires字段,可以指定缓存的过期时间,是一个具体的日期时间。在过期时间之前,客户端可以直接使用缓存的数据。已被Cache-Control代替。

强缓存策略优先于协商缓存策略,如果缓存数据仍然有效,客户端将直接使用缓存的数据,而无需向服务器发送请求。

  1. 协商缓存(Conditional Caching):协商缓存是通过在请求头中发送一些条件字段,与服务器进行通信,判断缓存的数据是否仍然有效。常见的协商缓存字段有:

    • If-Modified-Since:客户端发送上次获取资源时服务器返回的Last-Modified字段的值,服务器通过比较资源的最后修改时间判断缓存是否有效。
    • If-None-Match:客户端发送上次获取资源时服务器返回的ETag字段的值,服务器通过比较资源的标识符判断缓存是否有效。

如果缓存数据失效或者客户端发送了协商缓存的条件字段,服务器将根据条件判断是否返回新的数据。如果缓存仍然有效,服务器将返回一个304 Not Modified的响应,告知客户端可以继续使用缓存的数据,否则服务器将返回新的数据和相应的缓存字段。

浏览器发送请求使用缓存的整体流程:

image-20230806003439767

Cookie

Cookie是一种在客户端(通常是浏览器)存储数据的机制,用于跟踪和识别用户。它是由服务器发送给浏览器,并存储在浏览器的本地文件中的小型文本文件。

当用户访问一个网站时,服务器可以通过HTTP响应头中的Set-Cookie字段将一个或多个Cookie发送给浏览器。浏览器会将这些Cookie保存在本地,并在之后的每次请求中都将这些Cookie发送给服务器,以便服务器可以识别和跟踪用户的状态和行为。

标题说明
Name=value各种cookie的名称和值
Expires=DateCookie 的有效期,缺省时Cookie仅在浏览器关闭之前有效
Path=Path限制指定Cookie 的发送范围的文件目录,默认为当前
Domain=domain限制cookie生效的域名,默认为创建cookie的服务域名
secure仅在HTTPS 安全连接时,才可以发送Cookie
HttpOnlyJavaScript 脚本无法获得Cookie
SameSite=`[NoneStrictLax]`None 同站、跨站请求都可发送 Strict 仅在同站发送 Lax允许与级导航一起发送,并将与第三方网站发起的GET请求一起发送

HTTP2

HTTP/2(简称为HTTP2)是HTTP协议的一种新版本,旨在改进性能和效率。下面是HTTP/2的一些基本概念:

二进制传输:

HTTP/2使用二进制格式来传输数据,而不是HTTP/1.x中的文本格式。这种二进制格式的使用使得数据的解析和传输更加高效。

  • 帧(frame): HTTP/2 通信的最小单位,每个帧都包含帧头,至少也会标识出当前帧所属的数据流

  • 1.1响应是文本格式,而2.0把响应划分成了两个帧,HEADERS(首部)和 DATA(消息负载) 是帧的类型。

    一条HTTP响应,划分成了两个帧来传输,并且采用二进制来编码

    • 消息(Message): 与逻辑请求或响应消息对应的完整的一系列帧。特定消息的帧在同一个流上发送,这意味着一个HTTP请求或响应只能在一个流上发送。

    • 数据流(Frame): 已建立的TCP连接内的双向字节流,可以承载一条或多条消息

      image-20230806114352060

多路复用:

HTTP/2引入了多路复用的机制,允许在同一个TCP连接上同时发送多个请求和响应。这样可以避免建立多个连接的开销,提高资源利用率和性能。

在HTTP/2中,客户端和服务器之间建立一个持久的TCP连接,并通过这个连接进行通信。在这个连接上,可以同时传输多个请求和响应,而不需要为每个请求都建立一个新的连接。

多路复用的实现基于帧的概念。每个请求和响应被划分为多个帧,通过流标识符进行标识。这些帧可以以任意顺序发送和接收,而客户端和服务器可以根据流标识符将它们正确地组装成完整的请求和响应。

image-20230806114415625

HTTP/2 连接都是永久的,而且仅需要每个来源一个连接

Header 压缩:

HTTP/2使用了一种称为HPACK的压缩算法来压缩请求和响应的Header字段。这种压缩机制减小了数据的传输量,降低了网络延迟和带宽消耗。

服务器推送:

HTTP/2支持服务器主动推送数据给客户端,无需客户端明确请求。服务器可以根据客户端的请求,提前将相关资源推送给客户端,从而减少额外的请求延迟。

在传统的HTTP/1.x中,客户端需要发送一个请求来获取每个资源。例如,当客户端请求一个HTML页面时,服务器会返回HTML文件,并在HTML中包含其他相关的资源(如CSS、JavaScript、图像等)的链接。客户端在解析HTML并发现这些链接后,需要再次发送请求来获取这些资源。这样的过程会导致额外的延迟和网络开销。

而在HTTP/2中,服务器可以通过推送机制,在客户端请求之前将相关资源主动推送给客户端。服务器可以根据先前的请求和响应,预测客户端可能需要的资源,并将这些资源推送给客户端的缓存中。当客户端收到推送的资源时,它可以选择接受或拒绝这些资源。

image-20230806115021117

流和优先级:

HTTP/2引入了流的概念,将请求和响应分解为一个或多个独立的流进行传输。每个流都可以设置优先级,确保重要的请求和响应能够更快地传输和处理。

流控制:

阻止发送方向接收方发送大量数据的机制

HTTP/2相对于HTTP/1.x的优势在于更高的性能和更低的延迟。通过多路复用、Header压缩和服务器推送等机制,HTTP/2可以减少网络传输的开销,提高页面加载速度和用户体验。然而,为了使用HTTP/2,服务器和客户端都需要支持该协议,并且需要在网络环境中具备相应的支持。

HTTPS

HTTPS(HyperText Transfer Protocol Secure)是在HTTP基础上添加了安全性的通信协议,它使用SSL(Secure Sockets Layer)或TLS(Transport Layer Security)协议对通信进行加密和认证。

HTTPS的主要目的是保护网络通信的安全性,确保数据在传输过程中不被窃听、篡改或伪造。它在传输层对数据进行加密,使得第三方无法直接获取到明文数据。

image-20230806174516304

上图为运营上劫持模式,当你访问一个本来很正常的网页,但页面上却莫名其妙出现了一些广告标签、跳转脚本、欺骗性的红包按钮,甚至有时候本来要下载一个文件,最后下下来却变成了另外一个完全不同的东西,这些都是被运营商劫持了HTTP明文数据的现象。

为了解决HTTP明文传输数据可能导致的安全问题,1994年网景公司提出了HTTPS(HyperText Transfer Protocol Secure)超文本传输安全协议,数据通信仍然是HTTP,但利用SSL/TLS加密数据包

实现原理

  1. 用户在浏览器发起HTTPS请求(如 juejin.cn),默认使用服务端的443端口进行连接;
  2. HTTPS需要使用一套CA数字证书,证书内会附带一个公钥Pub,而与之对应的私钥Private保留在服务端不公开;
  3. 服务端收到请求,返回配置好的包含公钥Pub的证书给客户端;
  4. 客户端收到证书,校验合法性,主要包括是否在有效期内、证书的域名与请求的域名是否匹配,上一级证书是否有效(递归判断,直到判断到系统内置或浏览器配置好的根证书),如果不通过,则显示HTTPS警告信息,如果通过则继续;
  5. 客户端生成一个用于对称加密的随机Key,并用证书内的公钥Pub进行加密,发送给服务端;
  6. 服务端收到随机Key的密文,使用与公钥Pub配对的私钥Private进行解密,得到客户端真正想发送的随机Key
  7. 服务端使用客户端发送过来的随机Key对要传输的HTTP数据进行对称加密,将密文返回客户端;
  8. 客户端使用随机Key对称解密密文,得到HTTP数据明文;
  9. 后续HTTPS请求使用之前交换好的随机Key进行对称加解密。

image-20230806174920786

对称加密与非对称加密

对称加密和非对称加密是两种不同的加密算法,用于在信息传输中保护数据的安全性。

  1. 对称加密:

    • 对称加密使用相同的密钥(称为对称密钥)来进行加密和解密。发送方使用密钥将明文数据加密,接收方使用相同的密钥解密密文数据。
    • 优点:对称加密算法计算速度快,适合大量数据的加密和解密操作。
    • 缺点:密钥的安全性是对称加密的主要挑战。发送方和接收方必须事先共享密钥,并确保密钥不被未授权的人获取。
  2. 非对称加密:

    • 非对称加密使用一对密钥,分别是公钥和私钥公钥用于加密数据,私钥用于解密数据。公钥可以公开分享给任何人,而私钥必须保密。
    • 优点:非对称加密提供了更好的安全性,因为私钥只有接收方知道,不需要共享密钥。
    • 缺点:非对称加密算法计算速度较慢,适合加密少量数据或进行密钥交换。
  3. 组合使用:

    • 服务端有非对称加密的公钥A1,私钥A2;
    • 客户端发起请求,服务端将公钥A1返回给客户端;
    • 客户端随机生成一个对称加密的密钥K,用公钥A1加密后发送给服务端;
    • 服务端收到密文后用自己的私钥A2解密,得到对称密钥K,此时完成了安全的对称密钥交换,解决了对称加密时密钥传输被人窃取的问题
    • 之后双方通信都使用密钥K进行对称加解密。

CA颁发机构

依然考虑中间人攻击的情况,非对称加密的算法都是公开的,所有人都可以自己生成一对公钥私钥。

当服务端向客户端返回公钥A1的时候,中间人将其替换成自己的公钥B1传送给浏览器。

而浏览器此时一无所知,傻乎乎地使用公钥B1加密了密钥K发送出去,又被中间人截获,中间人利用自己的私钥B2解密,得到密钥K,再使用服务端的公钥A1加密传送给服务端,完成了通信链路,而服务端和客户端毫无感知。

HTTPS中间人HTTPS中间人

出现这一问题的核心原因是客户端无法确认收到的公钥是不是真的是服务端发来的。为了解决这个问题,互联网引入了一个公信机构,这就是CA。

服务端在使用HTTPS前,去经过认证的CA机构申请颁发一份数字证书,数字证书里包含有证书持有者、证书有效期、公钥等信息,服务端将证书发送给客户端,客户端校验证书身份和要访问的网站身份确实一致后再进行后续的加密操作。

但是,如果中间人也聪明一点,只改动了证书中的公钥部分,客户端依然不能确认证书是否被篡改,这时我们就需要一些防伪技术了。

前面说过,非对称加密中一般公钥用来加密,私钥用来解密,虽然私钥加密理论上可行,但由于数学上的设计这么做并不适合,那么私钥就只有解密这个功能了么?

私钥除了解密外的真正用途其实还有一个,就是数字签名,其实就是一种防伪技术,只要有人篡改了证书,那么数字签名必然校验失败。具体过程如下

  1. CA机构拥有自己的一对公钥和私钥
  2. CA机构在颁发证书时对证书明文信息进行哈希
  3. 将哈希值用私钥进行加签,得到数字签名

明文数据和数字签名组成证书,传递给客户端。

  1. 客户端得到证书,分解成明文部分Text和数字签名Sig1
  2. 用CA机构的公钥进行解签,得到Sig2(由于CA机构是一种公信身份,因此在系统或浏览器中会内置CA机构的证书和公钥信息)
  3. 用证书里声明的哈希算法对明文Text部分进行哈希得到T
  4. 当自己计算得到的哈希值H与解签后的Sig2相等,表示证书可信,没有被篡改

这时,签名是由CA机构的私钥生成的,中间人篡改信息后无法拿到CA机构的私钥,保证了证书可信。

注意,这里有一个比较难以理解的地方,非对称加密的签名过程是,私钥将一段消息进行加签,然后将签名部分和消息本身一起发送给对方,收到消息后对签名部分利用公钥验签,如果验签出来的内容和消息本身一致,表明消息没有被篡改。

在这个过程中,系统或浏览器中内置的CA机构的证书和公钥成为了至关重要的环节,这也是CA机构公信身份的证明,如果系统或浏览器中没有这个CA机构,那么客户端可以不接受服务端传回的证书,显示HTTPS警告。

实际上CA机构的证书是一条信任链,A信任B,B信任C,以掘金的证书为例,掘金向RapidSSL申请一张证书,而RapidSSL的CA身份是由DigiCert Global根CA认证的,构成了一条信任链。

各级CA机构的私钥是绝对的私密信息,一旦CA机构的私钥泄露,其公信力就会一败涂地。之前就有过几次CA机构私钥泄露,引发信任危机,各大系统和浏览器只能纷纷吊销内置的对应CA的根证书。

有些老旧的网站会要求使用前下载安装他自己的根证书,这就是这个网站使用的证书并不能在系统内置的CA机构和根证书之间形成一条信任链,需要自己安装根证书来构成信任链,这里的风险就要使用者自己承担了。

证书明细证书明细