当前位置: 首页 > news >正文

HTTP全攻略:从入门到精通

目录

  • 一、HTTP 基础入门
    • 1.1 HTTP 是什么
    • 1.2 HTTP 诞生背景与发展历程
    • 1.3 HTTP 工作原理
  • 二、HTTP 报文结构剖析
    • 2.1 请求报文结构详解
    • 2.2 响应报文结构详解
  • 三、HTTP 方法全解析
    • 3.1 常用 HTTP 方法介绍
    • 3.2 HTTP 方法的幂等性与安全性
  • 四、HTTP 状态码大揭秘
    • 4.1 状态码分类及含义
    • 4.2 常见状态码深入解读
  • 五、HTTP 版本演进与对比
    • 5.1 HTTP/1.1 特性与不足
    • 5.2 HTTP/2 新特性解析
    • 5.3 HTTP/3 变革与优势
  • 六、HTTP 与 HTTPS 的区别与联系
    • 6.1 HTTP 的安全风险
    • 6.2 HTTPS 如何解决安全问题
    • 6.3 HTTP 与 HTTPS 对比总结
  • 七、HTTP 缓存机制探秘
    • 7.1 缓存的作用与意义
    • 7.2 强制缓存与协商缓存
    • 7.3 缓存策略配置与优化
  • 八、实战应用与案例分析
    • 8.1 使用工具抓包分析 HTTP 通信
    • 8.2 Web 开发中 HTTP 的应用案例
  • 九、总结与展望
    • 9.1 HTTP 知识总结回顾
    • 9.2 HTTP 未来发展趋势展望


一、HTTP 基础入门

1.1 HTTP 是什么

HTTP,即超文本传输协议(Hypertext Transfer Protocol) ,是一种用于在计算机网络之间传输超文本和其他资源的应用层协议。它基于客户端 - 服务器模式,采用请求 - 响应模型,使得客户端(如浏览器)能够向服务器请求资源(如网页、图片、视频等),服务器则根据请求返回相应的响应。例如,当你在浏览器中输入一个网址并按下回车键时,浏览器会作为客户端向对应的服务器发送 HTTP 请求,服务器接收到请求后,将你所请求的网页内容(HTML 文件、CSS 样式、JavaScript 脚本等)返回给浏览器,浏览器再将这些内容解析并渲染成你看到的网页。

HTTP 协议运行在 TCP 协议之上,这保证了数据传输的可靠性。它是互联网上应用最为广泛的协议之一,是构建万维网(World Wide Web)的基础,对于互联网有着极其重要的影响。设计 HTTP 的最初目的是提供一种发布和接收超文本标记语言(HTML)页面的方法 ,随着互联网的发展,如今它已经远远超出了这个范畴,几乎支持传输任何类型的数据,实现各类应用资源超媒体访问的集成。

1.2 HTTP 诞生背景与发展历程

HTTP 的诞生可以追溯到 1989 年,由欧洲粒子物理学研究所的蒂姆・伯纳斯・李(Tim Berners-Lee)博士出于与远方的研究人员进行知识共享的目的提出。以下是 HTTP 主要版本的发展历程:

  • HTTP/0.9(1990 年):这是 HTTP 的第一个版本,结构非常简单,仅支持 GET 请求方法,功能单一,只能传输 HTML 格式的文本,并且在响应请求之后立即关闭连接,不支持请求头和响应头,也没有协议版本号的概念。在那个计算机处理能力低、存储容量小、网速很慢的时代,这样简洁的设计便于服务器与客户端处理。
  • HTTP/1.0(1996 年):引入了请求头和响应头的概念,允许在请求和响应中传递元数据信息,如浏览器类型、语言偏好、服务器信息等 。支持多种请求方法,如 GET、POST、HEAD 等,传输的数据不再仅限于文本,还可以是图片、音频、视频等多种类型。引入了协议版本号概念,形式上已经和现在的 HTTP 差别不大。然而,它每次请求都需要建立新的 TCP 连接,这导致性能相对较低,因为建立 TCP 连接需要进行三次握手,会带来一定的时间开销。
    HTTP/1.1(1997 年):近些年的主流协议,引入了持久连接(keep-alive),避免了每次请求都要重新建立连接的性能问题,多个请求可以共用同一个 TCP 连接,大大提高了传输效率。支持流水线方式,允许同时发送多个请求,而不需要等待前一个请求的响应。引入了缓存控制机制,使得客户端和服务器可以更好地管理缓存,减少不必要的数据传输。增加了 PUT、DELETE 等请求方法,使得对资源的操作更加丰富。强制要求 Host 头,使得互联网主机托管成为可能,也解决了一台服务器上托管多个网站的问题。支持分块传输编码,利于传输大文件,可以将大文件分成多个小块进行传输,而不需要一次性读取整个文件到内存中。
  • HTTP/2(2015 年):采用二进制协议,取代了 HTTP/1.x 的文本协议,减少了解析复杂性,提高了解析效率。引入了多路复用特性,允许在一个 TCP 连接上同时处理多个请求,而不会出现队头阻塞的问题,提高了并发性能。使用头部压缩技术(HPACK),减少了数据传输的大小,进一步提高了传输效率。支持服务器推送,服务器可以主动向客户端推送资源,减少了客户端的请求次数。
  • HTTP/3(2020 年):基于 UDP 协议的新一代 HTTP 协议,其基于 UDP 之上的 QUIC 协议,取代 TCP 作为传输层协议,旨在进一步提升性能和安全性。引入了 0-RTT 握手,加快了连接建立速度,使得在一些情况下可以更快地发送请求和接收响应。通过使用 UDP 协议,解决了 TCP 拥塞控制导致的队头阻塞问题,提高了传输的稳定性。支持更快的流控制和错误恢复机制,提高了传输的可靠性。

1.3 HTTP 工作原理

HTTP 基于客户端 - 服务器架构,其工作流程主要包括以下三个步骤:

  1. 客户端发起请求:客户端(如 Web 浏览器、手机 APP 等)通过 URL(统一资源定位符)向服务器发出 HTTP 请求。URL 不仅指明了要访问的资源位置,还包含了访问该资源所使用的协议(如 http:// 或 https:// )、服务器地址(域名或 IP 地址)、端口号(默认为 80 或 443)以及资源路径等信息。例如,当你在浏览器中输入https://www.example.com:8080/news/index.html,浏览器会解析这个 URL,然后根据其中的信息向对应的服务器(www.example.com,端口号 8080)发起请求,请求的资源路径是/news/index.html。请求消息包括请求行、请求头部、空行和请求数据四个部分。请求行包含请求方法(如 GET、POST 等)、URL 和 HTTP 版本;请求头部包含了一系列的键值对,用于传递关于客户端、请求内容等的元信息;空行用于分隔请求头部和请求数据;请求数据则是 POST 请求中需要发送到服务器的数据(GET 请求的数据通常包含在 URL 的查询参数中)。
  2. 服务器响应请求:服务器接收到客户端的请求后,会根据请求的内容进行相应的处理。服务器首先解析请求行和请求头部,了解客户端的需求和相关信息,然后根据请求的资源路径找到对应的资源(如 HTML 文件、数据库中的数据等),对资源进行处理(可能包括读取文件、查询数据库、调用其他服务等),最后将处理结果以 HTTP 响应的形式返回给客户端。响应消息包括状态行、消息报头、空行和响应正文四个部分。状态行包含 HTTP 版本、状态码和状态消息,状态码用于表示请求的处理结果(如 200 表示成功,404 表示资源未找到等);消息报头包含了关于服务器、响应内容等的元信息;空行用于分隔消息报头和响应正文;响应正文则是请求的资源内容(如 HTML 文件的内容、图片的二进制数据等)。
  3. 客户端处理响应:客户端接收到服务器的响应后,会根据响应内容进行处理。如果是 HTML 页面,浏览器会解析 HTML、CSS 和 JavaScript 代码,将页面渲染出来展示给用户;如果是文件下载请求,客户端会将响应正文保存为文件;如果是 API 调用,客户端会根据响应数据进行相应的业务逻辑处理。在处理过程中,客户端还会根据响应头部的信息进行一些操作,如根据缓存控制信息决定是否缓存响应内容,根据重定向状态码(如 301、302 等)进行页面跳转等。

二、HTTP 报文结构剖析

2.1 请求报文结构详解

HTTP 请求报文主要由三部分组成:请求行、请求头和请求正文。下面将详细介绍这三个部分。

  • 请求行:请求行是 HTTP 请求报文的第一行,包含三个重要信息:请求方法、URL 和 HTTP 版本 。请求方法用于指示客户端对服务器资源执行的操作,常见的有 GET、POST、PUT、DELETE 等。GET 方法常用于从服务器获取资源,请求的数据会附加在 URL 后面,以查询字符串的形式出现,例如https://example.com/search?keyword=HTTP,其中keyword=HTTP就是查询参数。POST 方法通常用于向服务器提交数据,比如用户登录时提交的用户名和密码,这些数据不会显示在 URL 中,而是放在请求正文中。PUT 方法用于更新服务器上的资源,DELETE 方法用于删除服务器上的资源。URL(Uniform Resource Locator)即统一资源定位符,它指定了要访问的资源的位置,不仅包含资源的路径,还可能包含服务器的域名、端口号等信息,例如https://www.example.com:8080/articles/123,其中https是协议,www.example.com是域名,8080是端口号,/articles/123是资源路径。HTTP 版本则标识了客户端使用的 HTTP 协议版本,如 HTTP/1.1、HTTP/2 等。

  • 请求头:请求头是一系列的键值对,位于请求行之后,用于传递关于客户端、请求内容以及请求的附加信息 。常见的请求头字段包括:

    • Host:指定请求的目标服务器的域名和端口号,HTTP/1.1 协议要求每个请求都必须包含 Host 头,这使得一台服务器可以托管多个网站,服务器能够根据 Host 头来确定客户端请求的是哪个网站的资源。例如,当你访问https://www.example.com和https://blog.example.com时,虽然它们可能指向同一台服务器,但通过 Host 头,服务器可以区分不同的请求。
    • User - Agent:包含发起请求的客户端软件的信息,如浏览器类型、版本、操作系统等 。例如,Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36表示这是一个运行在 Windows 10 系统上的 Chrome 浏览器发出的请求,服务器可以根据 User - Agent 头来为不同的客户端提供不同的内容或进行适配。
    • Accept:用于指定客户端能够接收的响应内容类型,如Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,表示客户端优先接收 HTML、XHTML 和 XML 格式的内容,q值表示权重,q=0.9表示对application/xml的接收优先级低于前两者 ,而对于其他类型(/)的接收优先级最低(q=0.8)。
    • Content - Type:当请求正文存在时,这个字段用于指定请求正文中数据的类型,常见的有application/x-www-form-urlencoded(用于表单数据,数据格式为key1=value1&key2=value2)、application/json(用于 JSON 格式的数据)、multipart/form-data(用于文件上传等,会将文件和其他表单数据一起发送)。
    • Cookie:客户端会通过这个头将保存在该请求域名下的所有 cookie 值发送给服务器,用于身份验证、记录用户状态等。例如,当用户登录网站后,服务器会返回一个包含用户身份信息的 cookie,客户端在后续请求中带上这个 cookie,服务器就能识别用户身份。
  • 请求正文:并非所有的请求都有请求正文,通常 GET 请求没有请求正文,因为 GET 请求主要是从服务器获取资源,数据通过 URL 的查询参数传递 。而 POST、PUT 等请求方法常用于向服务器提交或更新数据,这时请求正文就会包含要发送的数据 。例如,使用 POST 方法提交一个用户注册表单,请求正文可能是username=John&password=123456&email=john@example.com;如果是使用 JSON 格式发送数据,请求正文可能是{“username”: “John”, “password”: “123456”, “email”: “john@example.com”} 。请求正文的数据格式由 Content - Type 头指定。

2.2 响应报文结构详解

HTTP 响应报文同样由三部分组成:状态行、响应头和响应正文。

  • 状态行:状态行位于响应报文的第一行,包含三个信息:HTTP 版本、状态码和状态消息 。HTTP 版本标识服务器使用的 HTTP 协议版本,与请求报文中的 HTTP 版本相对应 。状态码是一个三位数字,用于表示服务器对请求的处理结果,常见的状态码有 200(表示请求成功,服务器已成功处理请求并返回了相应的资源)、404(表示服务器找不到请求的资源)、500(表示服务器内部发生错误,无法完成请求)等 。状态消息是对状态码的简短描述,例如 200 对应的状态消息通常是 “OK”,404 对应的是 “Not Found”,500 对应的是 “Internal Server Error”,它们用于更直观地向客户端传达请求处理的结果。
  • 响应头:响应头也是一系列的键值对,位于状态行之后,用于传递关于服务器、响应内容以及响应的附加信息 。常见的响应头字段包括:
    • Server:标识服务器软件的名称和版本,例如Server: Apache/2.4.41表示这是一台运行 Apache 2.4.41 版本的服务器,通过这个头,客户端可以了解服务器的相关信息。
    • Content - Type:指定响应正文的内容类型,与请求头中的 Content - Type 类似,例如Content-Type: text/html; charset=UTF-8表示响应正文是 HTML 格式,字符编码为 UTF - 8,客户端可以根据这个信息正确解析响应内容。
    • Content - Length:表示响应正文的长度(以字节为单位),客户端可以根据这个长度来准确读取响应数据,例如Content-Length: 1024表示响应正文的大小为 1024 字节。
    • Set - Cookie:服务器通过这个头向客户端设置 cookie,例如Set-Cookie: session_id=abc123; expires=Thu, 15 Jun 2024 12:00:00 GMT; path=/,表示设置一个名为session_id,值为abc123的 cookie,过期时间是 2024 年 6 月 15 日 12 点,路径为根路径/。
    • Cache - Control:用于控制缓存行为,例如Cache-Control: max-age=3600表示客户端可以将响应内容缓存 1 小时(3600 秒),在这期间再次请求相同资源时可以直接使用缓存,而不需要向服务器发送请求。
  • 响应正文:响应正文包含了服务器返回给客户端的实际资源内容,例如当客户端请求一个 HTML 页面时,响应正文就是该 HTML 页面的代码;如果请求的是一张图片,响应正文就是图片的二进制数据 。响应正文的内容类型由 Content - Type 头指定,客户端会根据 Content - Type 头来正确处理响应正文,如将 HTML 内容渲染成网页展示给用户,将图片数据显示为图片。

三、HTTP 方法全解析

3.1 常用 HTTP 方法介绍

在 HTTP 协议中,定义了多种请求方法,用于指示客户端对服务器资源执行的操作。以下是一些常用的 HTTP 方法:

  • GET:GET 方法是最常用的 HTTP 方法之一,主要用于从服务器获取指定的资源。在请求时,数据会以查询字符串的形式附加在 URL 后面 ,例如https://example.com/search?keyword=apple&page=1,其中keyword=apple和page=1就是查询参数 。GET 请求通常用于获取数据,对服务器资源没有修改作用,并且可以被缓存,也可以被收藏为书签 。不过,GET 请求由于数据暴露在 URL 中,不太适合传输敏感数据,并且有长度限制,不同浏览器对 URL 长度的限制不同,例如 IE 浏览器对 URL 长度限制在 2083 个字符左右,Chrome 浏览器则允许更长的 URL,但也有一定限制 。GET 请求一般用于获取静态资源(如图片、CSS 文件、JavaScript 文件等)、获取列表数据(如新闻列表、商品列表等)以及简单的查询操作(如根据关键词搜索文章)。
  • POST:POST 方法用于向服务器提交数据,请求的参数通常放在请求体中,而不是像 GET 方法那样附加在 URL 后面 。POST 请求常用于创建新资源(如用户注册、提交表单数据)、上传文件以及执行一些需要服务器处理的操作(如用户登录验证、订单提交) 。由于数据在请求体中传输,相对 GET 方法更安全,并且理论上没有数据长度限制 ,但实际应用中可能会受到服务器配置和网络环境的限制。例如,在一个电商网站中,用户下单时会将商品信息、数量、收货地址等数据通过 POST 请求发送到服务器进行处理 。POST 请求不会被缓存,也不会保留在浏览器历史记录中,这使得它更适合处理敏感信息和进行状态改变的操作。
  • PUT:PUT 方法用于更新服务器上的资源,它的语义是用请求中的数据替换目标资源的全部内容 。PUT 请求需要指定完整的资源 URL,并且请求体中包含要更新的资源的完整数据 。例如,要更新用户的信息,假设用户 ID 为 123,请求可能是PUT /users/123 HTTP/1.1,请求体中包含更新后的用户信息{“name”: “John Doe”, “age”: 30} 。如果资源不存在,PUT 方法也可以用于创建新资源 。在实际应用中,PUT 方法常用于更新数据库中的记录、更新文件内容等场景,比如在一个内容管理系统中,管理员可以使用 PUT 请求来更新一篇文章的内容。
  • DELETE:DELETE 方法用于删除服务器上指定的资源 。使用时,只需在请求行中指定要删除的资源的 URL 即可,例如DELETE /users/123 HTTP/1.1表示删除 ID 为 123 的用户资源 。DELETE 请求会改变服务器上资源的状态,删除指定的资源 。在一些云存储服务中,用户可以使用 DELETE 请求删除存储在云端的文件。
  • HEAD:HEAD 方法与 GET 方法类似,都用于向服务器请求资源 。但 HEAD 方法的响应只包含 HTTP 头部信息,不包含响应正文 。这使得 HEAD 方法非常适合用于获取资源的元信息,如检查资源是否存在(通过响应状态码判断)、获取资源的大小(通过 Content - Length 头)、获取资源的最后修改时间(通过 Last - Modified 头)等 。例如,当你想知道一个图片文件的大小,但又不想下载整个文件时,就可以使用 HEAD 请求。

3.2 HTTP 方法的幂等性与安全性

在 HTTP 协议中,幂等性和安全性是两个重要的概念,它们对于理解和正确使用 HTTP 方法非常关键。

  • 幂等性:幂等性是指对同一资源的一组请求,无论执行一次还是多次,其对资源的影响和结果都是相同的(除了错误或过期等特殊情况) 。用数学概念来理解,类似于函数f(f(x)) = f(x) 。从分布式系统设计角度来看,由于网络环境的复杂性,请求可能会出现重试的情况,幂等性可以保证在这种情况下系统状态的一致性 。在 HTTP 方法中,GET 方法是幂等的,因为多次使用 GET 请求获取同一个资源,得到的结果是相同的,不会对资源产生额外的影响 。例如,多次请求GET /products/123 HTTP/1.1,返回的都是 ID 为 123 的产品信息 。PUT 方法也是幂等的,假设使用PUT /users/123 HTTP/1.1请求来更新用户信息,无论这个请求执行一次还是多次,最终用户 ID 为 123 的信息都会被更新到相同的状态 。DELETE 方法同样具有幂等性,多次请求DELETE /users/123 HTTP/1.1,第一次请求会删除资源,返回 200 状态码,后续再请求,由于资源已不存在,会返回 404 状态码,但资源的最终状态都是不存在 。而 POST 方法通常是非幂等的,因为 POST 方法常用于创建新资源,每次执行 POST 请求都可能创建一个新的资源 。例如,在一个订单系统中,多次发送相同的创建订单的 POST 请求,会创建多个不同的订单,它们具有不同的订单 ID。
  • 安全性:HTTP 协议中的安全性是指请求方法不会对服务器资源产生副作用,即这些方法仅用于获取资源,而不会修改、删除或创建新的资源。安全的请求方法设计目的是确保客户端在请求资源时不会对服务器状态产生任何影响。GET 方法是安全的,因为它只是从服务器获取资源,不会对服务器上的资源进行任何修改 。例如,使用 GET 请求获取一篇文章的内容,不会改变文章本身的内容。HEAD 方法也是安全的,它和 GET 方法类似,只是不返回响应正文,同样不会对资源产生修改操作 。而 POST、PUT、DELETE 等方法是不安全的,POST 方法用于提交数据,可能会创建新资源或修改现有资源;PUT 方法用于更新资源;DELETE 方法用于删除资源,它们都会对服务器资源的状态产生改变。例如,使用 POST 方法提交用户注册信息,会在服务器上创建一个新的用户资源。

理解 HTTP 方法的幂等性和安全性,有助于开发者在设计和实现 Web 应用程序时,选择合适的 HTTP 方法,确保系统的可靠性和一致性。在分布式系统中,幂等性设计可以有效处理请求重试的情况,避免数据不一致的问题;而安全性的概念则帮助我们区分哪些操作是只读的,哪些会对资源进行修改,从而更好地保护服务器资源。

四、HTTP 状态码大揭秘

4.1 状态码分类及含义

HTTP 状态码是服务器在响应客户端请求时返回的三位数字代码,用于指示请求的处理结果。状态码的第一个数字定义了状态码的类型,共分为五类,具体如下:

  • 1xx(信息性状态码):表示临时响应并需要请求者继续执行操作的状态代码。这类状态码是 HTTP/1.1 协议新增的,在 HTTP/1.0 协议中没有定义。常见的 1xx 状态码有 100 Continue,当服务器收到客户端请求的初始部分,并且愿意继续接收请求的其余部分时,会返回 100 Continue 状态码,告知客户端可以继续发送请求。例如,在一个大型文件上传的场景中,客户端先发送了部分请求头信息,服务器返回 100 Continue,客户端就可以继续上传文件的主体部分。101 Switching Protocols 表示服务器已同意切换协议,比如从 HTTP 协议切换到 WebSocket 协议,当客户端在请求头中包含 Upgrade 头字段,请求升级协议时,如果服务器支持并同意切换,就会返回 101 Switching Protocols 状态码。
  • 2xx(成功状态码):表示请求已成功被服务器接收、理解并接受。这是最常见的一类状态码,其中 200 OK 是最常用的,表示请求已成功,服务器返回了请求的资源,无论是 GET 请求获取网页内容、POST 请求提交表单数据成功等,都可能返回 200 OK 状态码 。201 Created 通常用于 POST 请求,表示请求成功并且服务器创建了新的资源,响应中可能包含新资源的 URI,比如在用户注册场景中,服务器成功创建了新用户,就会返回 201 Created 状态码 。204 No Content 表示请求成功,但服务器没有返回任何内容,通常用于 PUT 或 DELETE 请求,表示操作成功但不需要返回数据,例如删除某个文件成功后,服务器可能返回 204 No Content 状态码。206 Partial Content 用于客户端进行了范围请求(如 Range 请求)的场景,表示服务器成功执行了部分 GET 请求,返回了部分内容,在视频分段播放、文件断点续传等场景中经常会用到,客户端可以根据返回的部分内容继续进行相应操作。
  • 3xx(重定向状态码):表示需要客户端采取进一步的操作才能完成请求,通常是重定向到另一个 URL。301 Moved Permanently 表示请求的资源已被永久移动到新位置,浏览器会自动重定向到新 URL,并且搜索引擎会更新索引,例如一个网站更换了域名,旧域名的页面返回 301 状态码,并在 Location 头中指定新域名的 URL,用户访问旧域名时会自动跳转到新域名 。302 Found(或 307 Temporary Redirect)表示请求的资源临时移动到新位置,浏览器会自动重定向到新 URL,但搜索引擎不会更新索引,在一些临时维护、页面调整等场景中会用到,用户后续请求还是建议使用原有 URL。304 Not Modified 表示资源未修改,客户端可以使用缓存的版本,当客户端发送附带条件的请求(如带有 If-Modified-Since 或 If-None-Match 头的请求)时,如果服务器判断资源未修改,就会返回 304 Not Modified 状态码,这样可以节省带宽和时间,减少不必要的数据传输。
  • 4xx(客户端错误状态码):表示客户端提交的请求存在错误。400 Bad Request 表示请求语法错误或包含无法理解的参数,比如客户端发送的 JSON 格式数据存在语法错误,服务器无法解析,就会返回 400 Bad Request 状态码。401 Unauthorized 表示请求需要用户身份验证,客户端可能需要提供用户名和密码,或者使用 API 密钥等进行认证,当用户未登录却访问需要登录权限的页面时,服务器会返回 401 Unauthorized 状态码。403 Forbidden 表示服务器理解请求但拒绝执行,通常是因为权限不足,客户端即使提供了正确的凭据也无法访问资源,比如普通用户试图访问管理员权限的页面,就会收到 403 Forbidden 状态码。404 Not Found 表示服务器找不到请求的资源,可能是 URL 拼写错误,或者资源确实不存在,当用户访问一个不存在的网页时,服务器会返回 404 Not Found 状态码。405 Method Not Allowed 表示请求方法(如 GET、POST)对指定资源不适用,服务器只允许特定的方法访问该资源,例如某个接口只允许 POST 方法访问,客户端却使用了 GET 方法,就会返回 405 Method Not Allowed 状态码 。429 Too Many Requests 表示客户端发送的请求过于频繁,触发了服务器的速率限制,服务器会在响应头中包含 Retry-After 字段,告诉客户端何时可以再次尝试,在一些 API 接口为了防止恶意请求、保护服务器资源时会设置速率限制,当客户端请求超过限制时就会返回 429 Too Many Requests 状态码。
  • 5xx(服务器错误状态码):表示服务器在处理请求时遇到问题。500 Internal Server Error 是一个通用的错误代码,表示服务器遇到了意外情况,无法完成请求,通常是由于服务器端的脚本错误、配置问题或资源不足等原因引起的,比如服务器端的代码出现语法错误、数据库连接失败等,都会返回 500 Internal Server Error 状态码。
    • 501 Not Implemented 表示服务器不支持请求的功能,例如客户端发送了一个服务器不支持的 HTTP 方法,服务器就会返回 501 Not Implemented 状态码。
    • 502 Bad Gateway 表示服务器作为网关或代理,从上游服务器收到无效响应,这通常是由于后端服务器故障或配置错误导致的,比如后端服务器崩溃、网关配置错误等。
    • 503 Service Unavailable 表示服务器暂时无法处理请求,可能是由于过载或维护,通常会在响应头中包含 Retry-After 字段,告诉客户端何时可以再次尝试,在服务器进行定期维护、负载过高时会返回 503 Service Unavailable 状态码。
    • 504 Gateway Timeout 表示服务器作为网关或代理,未能及时从上游服务器获取响应,通常是由于网络延迟或上游服务器响应超时,比如网络不稳定、上游服务器处理请求过慢等。

4.2 常见状态码深入解读

下面对一些常见的 HTTP 状态码进行更深入的解读:

  • 200(成功):200 OK 是 HTTP 协议中最常见的成功状态码。当客户端发送的请求被服务器成功处理时,服务器会返回 200 OK 状态码,并在响应正文中包含请求所期望的资源内容。例如,当用户在浏览器中输入一个正确的网址并访问时,如果服务器正常运行且能够找到用户请求的网页资源,就会返回 200 OK 状态码,同时将网页的 HTML 代码、相关的 CSS 样式、JavaScript 脚本以及图片等资源数据一并返回给浏览器,浏览器再将这些内容解析并渲染成用户看到的网页。在 API 调用中,当客户端发送一个 GET 请求获取数据,服务器成功从数据库中查询到对应的数据并返回时,也会返回 200 OK 状态码,响应正文就是查询到的数据(通常以 JSON、XML 等格式返回)。200 OK 状态码意味着整个请求 - 响应过程顺利完成,客户端可以根据返回的资源内容进行下一步的操作,无论是展示给用户还是进行后续的业务逻辑处理。
  • 301(永久重定向):301 Moved Permanently 表示请求的资源已被永久移动到新的位置。当服务器返回 301 状态码时,会在响应头的 Location 字段中指明新的资源 URL。例如,一个电商网站对商品详情页面的 URL 进行了重新规划,原来的商品详情 URL 格式为https://www.example.com/products?id=123,现在改为https://www.example.com/products/123,当用户访问旧的 URL 时,服务器会返回 301 状态码,并在 Location 头中设置为新的 URLhttps://www.example.com/products/123,浏览器接收到这个响应后,会自动重定向到新的 URL,并且搜索引擎在抓取网页时,也会更新索引,将旧 URL 对应的索引更新为新 URL,这样可以确保用户和搜索引擎在后续访问时都能找到正确的资源位置。301 重定向常用于网站改版、域名更换等场景,通过永久重定向,可以保证用户在访问旧资源时能够顺利跳转到新资源,同时也有助于搜索引擎优化(SEO),避免旧 URL 的权重丢失。
  • 302(临时重定向):302 Found(或 307 Temporary Redirect)表示请求的资源临时从不同的 URI 响应请求,但请求者应继续使用原有位置来进行以后的请求。与 301 不同,302 重定向只是临时的,搜索引擎不会更新索引。例如,一个新闻网站正在进行页面的临时调整,将某个新闻详情页临时转移到另一个 URL 进行展示,但这只是一个临时的操作,之后可能会恢复到原来的 URL。当用户访问原新闻详情页的 URL 时,服务器返回 302 状态码,并在 Location 头中指定临时的 URL,浏览器会自动跳转到临时 URL 展示新闻内容,但用户下次访问时,仍然建议使用原 URL。在一些限时活动页面、临时维护页面等场景中,经常会用到 302 重定向,它可以在不改变用户习惯访问路径的前提下,临时将用户引导到其他资源位置,待临时情况结束后,用户仍可通过原 URL 正常访问。
  • 404(未找到):404 Not Found 状态码表示服务器无法找到请求的资源。这可能是由于多种原因导致的,比如用户输入的 URL 拼写错误,将https://www.example.com/article/123误输为https://www.example.com/articl/123,服务器在解析 URL 后,无法找到对应的资源,就会返回 404 状态码;或者资源确实被删除、移动到其他位置且未进行重定向设置,例如一篇文章被管理员删除后,用户再访问该文章的 URL,服务器也会返回 404 状态码。对于网站开发者来说,通常会为 404 状态码设置一个用户友好的错误页面,告知用户所请求的资源未找到,并提供一些有用的信息,如返回首页的链接、搜索框等,以帮助用户找到他们真正需要的内容。在网站的日志分析中,404 状态码出现的频率可以反映出网站的一些问题,比如是否存在大量无效链接、用户是否经常输入错误的 URL 等,通过分析这些数据,可以对网站进行优化,提高用户体验。
  • 500(内部服务器错误):500 Internal Server Error 是服务器在处理请求时遇到意外错误时返回的状态码。它通常表示服务器端的代码出现问题、配置错误或者服务器资源不足等情况。例如,服务器端的 PHP 脚本存在语法错误,当客户端发送请求触发该脚本执行时,由于脚本无法正确解析和执行,服务器就会返回 500 Internal Server Error 状态码;或者服务器在与数据库进行交互时,出现数据库连接超时、查询语句错误等问题,导致无法获取或更新数据,也会返回 500 状态码。对于服务器管理员来说,当收到 500 状态码的反馈时,需要查看服务器的错误日志,以了解具体的错误原因。错误日志中可能会包含详细的错误信息,如错误发生的文件路径、行数、错误类型等,根据这些信息,管理员可以定位并修复问题,例如修改代码错误、重新配置数据库连接参数、增加服务器资源(如内存、CPU 等)。同时,为了提高系统的安全性,500 状态码返回给客户端的响应通常不会包含详细的错误信息,以免泄露服务器的敏感信息。

五、HTTP 版本演进与对比

5.1 HTTP/1.1 特性与不足

HTTP/1.1 作为 HTTP 协议的重要版本,在互联网发展历程中扮演了重要角色,具有一系列显著特性,同时也存在一些不足之处。

  • 特性

    • 持久连接(Persistent Connections):HTTP/1.1 引入了持久连接机制,允许在同一个 TCP 连接上进行多个 HTTP 请求和响应,避免了每次请求都要重新建立 TCP 连接的开销。在 HTTP/1.0 中,每个请求 - 响应周期都需要建立新的 TCP 连接,而建立 TCP 连接需要进行三次握手,这会带来一定的时间延迟。例如,一个网页包含多个图片、CSS 文件和 JavaScript 脚本,如果使用 HTTP/1.0,每次请求这些资源都要重新建立连接,而使用 HTTP/1.1 的持久连接,只需要建立一次 TCP 连接,就可以连续请求所有资源,大大提高了传输效率,减少了页面加载时间。
    • 管道化(Pipelining):在持久连接的基础上,HTTP/1.1 支持管道化,即客户端可以在未收到前一个请求的响应时,就发送下一个请求 。这样可以进一步提高请求的并发性,减少等待时间。比如,客户端需要请求多个图片资源,使用管道化技术,它可以连续发送多个图片请求,而不需要等待第一个图片请求的响应返回后再发送第二个请求,理论上可以加快资源的获取速度。
    • 缓存控制(Cache Control):HTTP/1.1 引入了更灵活的缓存控制机制,通过 Cache-Control 和 Expires 等头字段,服务器和客户端可以更好地管理缓存 。服务器可以指定资源的缓存策略,如设置缓存过期时间、是否允许缓存等;客户端则可以根据这些策略来决定是否使用缓存的资源,而不需要每次都向服务器发送请求 。例如,对于一些不经常更新的静态资源(如图片、CSS 文件),服务器可以设置较长的缓存过期时间,客户端在缓存有效期内再次请求这些资源时,直接从本地缓存中获取,减少了网络流量和服务器负载。
    • Host 头字段:HTTP/1.1 强制要求请求中包含 Host 头字段,这使得一台服务器可以托管多个网站 。服务器可以根据 Host 头来确定客户端请求的是哪个网站的资源,从而实现虚拟主机的功能 。例如,在同一台服务器上,可以同时部署www.example.com和www.another.com两个网站,客户端请求时通过 Host 头指定具体的域名,服务器就能正确地返回对应的网站内容。
    • 分块传输编码(Chunked Transfer Encoding):该特性允许服务器将响应数据分成多个小块进行传输,而不需要在发送响应前知道整个响应的大小 。这对于传输大文件或动态生成的内容非常有用,因为服务器不需要一次性生成整个响应数据并存储在内存中 。例如,在下载一个大视频文件时,服务器可以将视频数据分成多个块依次发送给客户端,客户端在接收过程中可以逐步处理这些数据,而不需要等待整个文件下载完成。
  • 不足

    • 队头阻塞(Head - of - Line Blocking):HTTP/1.1 虽然支持管道化,但由于 HTTP 请求和响应是按顺序处理的,当一个请求在传输或处理过程中出现延迟(比如服务器处理某个请求时间过长,或者网络拥塞导致某个请求的响应延迟),后续的请求即使已经准备好发送或处理,也必须等待前面的请求完成 。例如,一个网页有多个资源请求通过同一个 TCP 连接发送,其中一个 JavaScript 文件的请求因为服务器繁忙而长时间未响应,那么后面的图片、CSS 文件等请求都只能在队列中等待,这会导致整个页面的加载速度受到影响。
    • 文本格式导致的开销:HTTP/1.1 的报文采用文本格式,这使得报文的解析和生成相对复杂,并且会增加数据传输的大小 。文本格式需要使用额外的字符来表示字段分隔、换行等信息,而且对于一些重复的头部信息(如 User - Agent、Cookie 等),每次请求都要完整传输,没有有效的压缩机制 。相比之下,二进制格式在解析效率和数据传输大小上更具优势。
    • 并发连接数量限制:虽然 HTTP/1.1 允许使用持久连接和管道化来提高传输效率,但浏览器通常会限制对同一域名的并发连接数量(例如,Chrome 浏览器默认对同一域名的并发连接数限制为 6 个) 。这意味着在需要同时请求大量资源时,仍然无法充分利用网络带宽,影响页面加载速度 。例如,一个页面包含大量图片、脚本和样式文件,如果并发连接数量有限,就需要分批次请求这些资源,导致整体加载时间变长。

5.2 HTTP/2 新特性解析

HTTP/2 是 HTTP 协议的一次重大升级,引入了多项新特性,旨在解决 HTTP/1.1 存在的性能瓶颈和限制,显著提升了 Web 性能。

  • 二进制分帧(Binary Framing):HTTP/2 使用二进制格式对请求和响应进行分帧,取代了 HTTP/1.1 中的文本格式。它将数据分割为更小的帧(Frame),每个帧都有特定的类型和标识,例如,“Headers” 帧存放头数据,“DATA” 帧存放实体数据 。这种二进制编码方式使得数据解析更加高效,因为计算机处理二进制数据比处理文本数据速度更快 。同时,二进制分帧还提高了数据传输的可靠性,减少了因文本格式解析错误导致的问题 。例如,在传输一个包含大量头部信息和正文数据的 HTTP 请求时,HTTP/1.1 的文本格式需要逐字解析,而 HTTP/2 的二进制分帧可以快速识别帧类型和数据内容,大大缩短了解析时间。
  • 多路复用(Multiplexing):HTTP/2 引入了多路复用机制,允许在单个 TCP 连接上同时发送多个请求和响应 。它定义了一个 “流”(Stream)的概念,流是二进制帧的双向传输序列,同一个消息往返的帧会分配一个唯一的流 ID。通过流,HTTP/2 可以在一个 TCP 连接上同时发送多个 “碎片化” 的消息,这些消息的帧在传输过程中可以乱序到达,接收端会根据流 ID 将它们重新组装成完整的请求或响应 。例如,在加载一个包含多个资源(如 HTML、CSS、JavaScript、图片等)的网页时,HTTP/2 可以将这些资源的请求和响应通过同一个 TCP 连接并发传输,而不需要像 HTTP/1.1 那样为每个资源建立单独的连接,或者在一个连接上按顺序依次处理请求,从而避免了队头阻塞问题,极大地提高了连接利用率和传输效率。
  • 头部压缩(Header Compression):HTTP/2 使用 HPACK 算法对 HTTP 头部进行压缩,以减少头部的大小 。HPACK 算法通过在客户端和服务器端同时维护一张头信息表,对于重复出现的头部字段,只发送索引号,而不是完整的字段内容 。例如,在多次请求中,User - Agent 字段可能保持不变,HTTP/2 在第一次发送完整的 User - Agent 字段后,后续请求中只需发送该字段在头信息表中的索引号,从而减少了头部数据的传输量 。此外,HPACK 还使用 Huffman 编码对头部数据进行进一步压缩,可达到 50% - 90% 的高压缩率 ,这在移动网络等带宽受限的环境中效果尤为显著,能够有效降低网络传输延迟和带宽消耗。
  • 服务器推送(Server Push):HTTP/2 支持服务器主动推送资源给客户端,无需客户端明确请求 。服务器可以根据客户端的请求,预测客户端可能需要的其他资源,并在响应中主动将这些资源推送给客户端 。例如,当浏览器请求一个 HTML 页面时,服务器可以同时推送该页面所需的 CSS 和 JavaScript 文件,这样客户端在解析 HTML 时,就可以直接使用已推送的 CSS 和 JavaScript 资源,而不需要再额外发送请求去获取它们,减少了客户端发起额外请求的次数,降低了往返时间(RTT),提高了页面加载速度和性能。
  • 流量控制(Flow Control):HTTP/2 可以对连接和流进行流量控制,防止数据发送方发送数据过快,导致接收方来不及处理而造成数据丢失或缓冲区溢出 。它通过在帧中设置窗口大小等字段,接收方可以告知发送方自己的接收能力,发送方根据这些信息来调整数据发送速率 。例如,当客户端的网络状况不佳或者处理能力有限时,它可以通过流量控制机制通知服务器降低数据发送速度,保证数据传输的稳定性和可靠性。
  • 优先级设置(Stream Prioritization):HTTP/2 引入了流和优先级的概念,允许客户端为不同的请求设置优先级,服务器可以根据优先级来决定先处理哪些请求。例如,对于一个网页,HTML 文件的请求优先级可以设置得较高,因为它是构建页面的基础,只有先获取并解析 HTML 文件,才能进一步请求和处理其他资源(如 CSS、JavaScript、图片等) 。通过优先级设置,服务器能够更好地管理和调度资源,确保关键资源优先传输和处理,提供更好的用户体验。

5.3 HTTP/3 变革与优势

HTTP/3 是 HTTP 协议的又一次重大演进,基于 UDP 协议的 QUIC(Quick UDP Internet Connections)实现,带来了一系列变革和显著优势,进一步提升了网络性能和用户体验。

  • 基于 QUIC 协议:HTTP/3 将传输层从 TCP 替换为 UDP,并在 UDP 之上实现了 QUIC 协议 。UDP 是一种无连接、不可靠的传输协议,与 TCP 相比,它的传输速度更快,延迟更低 。然而,UDP 缺乏 TCP 的可靠性机制(如数据重传、拥塞控制等),而 QUIC 在 UDP 的基础上,增加了这些可靠性和拥塞控制功能,同时还集成了 TLS 加密功能 。例如,QUIC 使用 TLS 1.3 进行加密,提供了更安全的通信通道,并且在握手过程中减少了 RTT(Round - Trip Time,往返时间)的消耗 。通过使用 QUIC 协议,HTTP/3 既利用了 UDP 的速度优势,又保证了数据传输的可靠性和安全性。
  • 0 - RTT 握手(0 - Round - Trip Time Handshake):HTTP/3 的 QUIC 协议实现了快速握手功能,可以使用 0 - RTT 或者 1 - RTT 来建立连接 。在传统的 TCP 连接中,建立连接需要进行三次握手,这至少需要 1 个 RTT 的时间 。而在 HTTP/3 中,首次连接时,客户端可以在发送第一个数据包时就携带请求数据,服务器在收到数据包后,能够直接处理请求,无需等待额外的握手过程,从而大大提升了首次打开页面的速度 。对于后续的连接,如果客户端和服务器都保存了之前的会话密钥,就可以实现 0 - RTT 握手,直接发送请求数据,进一步减少了连接建立的延迟 。例如,用户在频繁访问同一个网站时,使用 HTTP/3 的 0 - RTT 握手,能够更快地获取页面内容,提升了用户体验。
  • 解决队头阻塞问题:在 HTTP/2 中,虽然在应用层通过多路复用解决了请求层面的队头阻塞问题,但在 TCP 层仍然存在队头阻塞问题 。当 TCP 数据包在传输过程中丢失时,即使其他数据包已经到达,也必须等待丢失的数据包重传并确认后,才能将数据交付给应用层。而 HTTP/3 基于 UDP 的 QUIC 协议,由于 UDP 是无序的,包之间没有依赖关系,一个数据包的丢失不会影响其他数据包的传输和处理 。QUIC 实现了在同一物理连接上可以有多个独立的逻辑数据流,每个数据流(类似于 HTTP/2 中的流)都可以独立传输和处理,从而从根本上解决了队头阻塞问题,提高了传输的稳定性和效率。例如,在网络状况不佳的情况下,使用 HTTP/3 传输数据,即使部分数据包丢失,其他数据包仍然可以继续传输和被应用层使用,减少了数据传输的延迟和卡顿。
  • 连接迁移(Connection Migration):TCP 连接是基于四元组(源 IP、源端口、目的 IP、目的端口)来确定的,当客户端的网络发生变化(如从 Wi - Fi 切换到移动数据网络)时,至少会有一个因素发生变化,导致 TCP 连接需要重新建立。而 HTTP/3 的 QUIC 协议使用一个 64 位的随机数作为 Connection ID 来标识连接。只要 Connection ID 不变,即使客户端的 IP 地址或端口发生变化,连接仍然可以维持,无需重新建立 。这使得在移动设备频繁切换网络的场景下,HTTP/3 能够保持连接的稳定性,减少了因连接重建带来的延迟和数据丢失 。例如,用户在乘坐地铁时,手机从一个基站的网络切换到另一个基站的网络,使用 HTTP/3 的应用可以在不中断连接的情况下继续进行数据传输,保证了应用的流畅运行。

六、HTTP 与 HTTPS 的区别与联系

6.1 HTTP 的安全风险

HTTP 作为一种应用广泛的超文本传输协议,采用明文传输数据,这使其存在诸多安全风险,对用户信息和网络通信安全构成威胁。

  • 窃听风险:由于 HTTP 传输的数据是明文形式,在数据传输过程中,中间人(如网络黑客、恶意攻击者或处于不安全网络环境中的第三方)可以轻易地截获通信内容。例如,当用户在 HTTP 网站上进行登录操作时,用户名和密码会以明文形式在网络中传输,中间人一旦获取到这些数据,就能直接获取用户的敏感信息,进而利用这些信息进行非法活动,如登录用户的其他关联账户,获取更多隐私信息或进行诈骗等行为。
  • 篡改风险:同样因为数据明文传输,中间人不仅可以窃听,还能够在传输过程中对数据进行篡改。以在线购物场景为例,当用户通过 HTTP 协议提交订单信息时,中间人可以修改订单中的商品数量、价格等关键信息,然后将修改后的订单发送给商家。这样一来,商家收到的订单信息与用户原本提交的不一致,可能导致交易纠纷,损害用户和商家的利益。此外,对于一些重要的通知、公告等内容,中间人篡改后可能会误导用户,造成更严重的后果。
  • 冒充风险:HTTP 协议在通信过程中无法对通信方的身份进行有效认证。这使得攻击者有机会冒充合法的服务器或客户端进行通信。比如,用户在访问某个 HTTP 网站时,可能会被重定向到一个钓鱼网站,这个钓鱼网站的页面与用户原本要访问的合法网站页面极为相似,但实际上是攻击者创建的,用于骗取用户的登录信息、银行卡号等敏感数据。由于 HTTP 协议无法识别通信方的真实身份,用户很难察觉自己正在与假冒的网站进行交互,从而陷入安全陷阱。

6.2 HTTPS 如何解决安全问题

HTTPS 通过引入 SSL/TLS 协议,有效地解决了 HTTP 存在的安全问题,为网络通信提供了更高的安全性保障。

  • 加密通信:HTTPS 采用混合加密模式,结合了对称加密和非对称加密的优点。在通信建立之前,客户端和服务器使用非对称加密的方式交换会话密钥。例如,服务器将自己的公钥放入数字证书中发送给客户端,客户端验证证书的合法性后,生成一个随机的会话密钥,并用服务器的公钥对其进行加密,再发送给服务器。服务器使用私钥解密,得到会话密钥。之后在通信过程中,双方使用这个会话密钥进行对称加密来传输数据,因为对称加密的运算速度快,能够满足大量数据传输的效率要求,同时又利用非对称加密保证了会话密钥传输的安全性,防止密钥被窃取,从而解决了 HTTP 明文传输导致的窃听风险。
  • 身份认证:通过数字证书来实现身份认证。数字证书由受信任的证书颁发机构(CA,Certificate Authority)颁发,包含了服务器的公钥、颁发者信息、有效期等内容。服务器在与客户端建立连接时,会将数字证书发送给客户端。客户端会验证证书的合法性,包括检查证书是否由可信任的 CA 颁发、证书是否过期、证书中的域名是否与当前访问的域名一致等。如果证书验证通过,客户端就可以确认服务器的身份是真实可靠的,从而防止了攻击者冒充合法服务器进行通信,解决了 HTTP 中的冒充风险问题。
  • 保证数据完整性:利用摘要算法来实现数据完整性保护。在数据传输前,发送方会对数据进行摘要计算,生成一个固定长度的摘要值,然后用会话密钥对数据和摘要值进行加密后发送给接收方。接收方收到数据后,使用相同的摘要算法对解密后的数据进行摘要计算,得到一个新的摘要值,并与接收到的摘要值进行对比。如果两个摘要值相同,说明数据在传输过程中没有被篡改;如果不同,则说明数据可能已被篡改,接收方可以拒绝接受数据。例如,常见的摘要算法有 MD5、SHA - 1、SHA - 256 等,其中 SHA - 256 由于其安全性较高,在 HTTPS 中被广泛应用,有效地解决了 HTTP 数据传输过程中的篡改风险问题。

6.3 HTTP 与 HTTPS 对比总结

HTTP 和 HTTPS 在安全性、连接状态、端口号、性能等方面存在明显的差异,具体对比如下:

  • 安全性:HTTP 是明文传输协议,数据在传输过程中容易被窃听、篡改和冒充,安全性较低,不适合传输敏感信息,如用户密码、银行卡号等。而 HTTPS 通过 SSL/TLS 协议对数据进行加密、身份认证和完整性保护,能够有效防止数据泄露、篡改和伪造,安全性显著提高,常用于对安全性要求较高的场景,如网上银行、电子商务等。
  • 连接状态:HTTP 的连接是明文传输,一旦被截断,数据就可能被窃取或篡改,安全性无法得到保障。HTTPS 连接在数据传输过程中始终保持加密状态,即使连接在传输过程中被截断,数据也是加密的,攻击者难以获取明文数据,安全性更高。
  • 端口号:HTTP 通常使用 80 端口进行通信,这是 HTTP 协议的默认端口。HTTPS 则使用 443 端口,这个端口是为 HTTPS 协议专门分配的,用于建立安全的加密连接。
  • 性能:由于 HTTPS 需要进行加密和解密操作,在数据传输过程中需要消耗更多的计算资源,包括 CPU 的运算时间和内存的占用等,这可能导致其性能略低于 HTTP。但是,随着硬件性能的提升和加密算法的优化,以及缓存和复用技术的应用,HTTPS 与 HTTP 在性能上的差距已经逐渐缩小,在大多数情况下,用户几乎感觉不到这种性能差异。例如,现代浏览器和服务器都对 HTTPS 的性能进行了优化,采用了会话复用、硬件加速等技术,使得 HTTPS 在实际应用中能够提供高效的服务。

七、HTTP 缓存机制探秘

7.1 缓存的作用与意义

HTTP 缓存是一种在客户端和服务器之间实现的缓存机制,它允许浏览器和缓存服务器在多个请求之间重复使用数据,在现代 Web 应用中扮演着至关重要的角色,具有多方面的作用与重大意义。

  • 减少网络传输:当用户访问网页时,浏览器会首先检查缓存中是否存在所需的资源。如果缓存命中,浏览器直接从本地缓存中获取资源,而不需要再次从服务器下载。这极大地减少了网络数据的传输量,尤其是对于那些不经常更新的静态资源,如图片、CSS 文件、JavaScript 脚本等,缓存可以避免重复下载,节省带宽资源。例如,一个包含大量图片和脚本的电商网站,用户首次访问后,这些资源被缓存,再次访问时,大部分资源直接从缓存获取,减少了数据流量的消耗。
  • 提高响应速度:从本地缓存读取资源的速度远远快于从服务器获取资源的速度。缓存机制可以显著缩短页面的加载时间,提升用户体验。在移动网络环境下,网络延迟和带宽限制更为明显,缓存的作用更加突出。用户能够更快地看到网页内容,减少等待时间,这对于提高用户满意度和网站的可用性至关重要。例如,在使用手机访问新闻类 APP 时,缓存的文章和图片可以在无网络或弱网络环境下快速加载显示,为用户提供更好的阅读体验。
  • 降低服务器负载:由于部分请求可以直接从缓存中得到响应,服务器不需要处理这些重复的请求,从而降低了服务器的负载。这使得服务器能够处理更多其他的请求,提高了服务器的整体性能和稳定性。对于高并发访问的网站或应用,缓存可以有效地减轻服务器的压力,避免服务器因过载而出现故障。例如,一个热门的在线视频平台,通过合理利用缓存,减少了对视频文件的重复请求,使得服务器能够承载更多用户的观看请求,保障了视频播放的流畅性。

7.2 强制缓存与协商缓存

HTTP 缓存主要分为强制缓存和协商缓存,它们在缓存机制中发挥着不同的作用,通过不同的方式来实现资源的有效缓存和利用。

  • 强制缓存:强制缓存是指浏览器在请求资源时,首先检查本地缓存中是否存在该资源,并且该资源是否在有效期内。如果缓存命中且资源未过期,浏览器直接从本地缓存中获取资源,不会向服务器发送请求。强制缓存的有效期主要通过 HTTP 响应头中的 Cache-Control 和 Expires 字段来控制。Cache-Control 是 HTTP/1.1 协议中定义的字段,它有多个属性值,其中 max-age 属性用于指定资源的最大缓存时间,单位为秒。例如,Cache-Control: max-age=3600表示资源在 3600 秒(1 小时)内有效,在这 1 小时内再次请求该资源,浏览器会直接使用缓存。此外,还有 no-cache 表示不使用本地缓存,需要使用协商缓存;no-store 表示直接禁止浏览器缓存数据,每次请求都向服务器获取完整资源;public 表示可以被所有用户缓存,包括终端用户和 CDN 等中间件代理服务器;private 表示只能被终端用户的浏览器缓存。Expires 是 HTTP/1.0 协议中定义的字段,它的值是一个绝对时间的 GMT 格式的时间字符串,表示资源的过期时间。例如,Expires: Wed, 29 Feb 2024 12:00:00 GMT,如果当前时间在这个过期时间之前,则命中缓存。但 Expires 存在一个缺点,它依赖于客户端的时间,如果客户端时间不准确,可能会导致缓存混乱,所以在实际应用中,Cache-Control 的优先级高于 Expires ,更常被使用。
  • 协商缓存:当强制缓存失效后,浏览器会发起请求到服务器,这时协商缓存开始工作。协商缓存是由服务器来确定缓存资源是否可用,主要涉及到两对属性字段:Last-Modified/If-Modified-Since 和 Etag/If-None-Match。Last-Modified/If-Modified-Since:Last-Modified 表示资源在服务器上的最后修改时间,服务器在响应头中返回这个时间。当浏览器再次请求该资源时,会在请求头中带上 If-Modified-Since 字段,其值为上次服务器返回的 Last-Modified 时间。服务器接收到请求后,比较 If-Modified-Since 和当前资源的最后修改时间,如果资源没有变化,服务器返回 304 Not Modified 状态码,浏览器直接使用本地缓存;如果资源有变化,服务器返回 200 OK 状态码,并返回新的资源内容和新的 Last-Modified 时间。Etag/If-None-Match:Etag 是服务器为每个资源生成的唯一标识字符串,只要资源有变化,这个值就会改变。服务器在响应头中返回 Etag,浏览器再次请求时,在请求头中带上 If-None-Match 字段,其值为上次服务器返回的 Etag。服务器比较 If-None-Match 和当前资源的 Etag,如果两者一致,服务器返回 304 Not Modified 状态码,浏览器使用本地缓存;如果不一致,服务器返回 200 OK 状态码,并返回新的资源内容和新的 Etag。Etag 的出现主要是为了解决 Last-Modified 存在的一些问题,比如某些文件可能会周期性更改但内容不变,或者文件修改非常频繁(秒级以下),Last-Modified 能检查到的粒度是秒级的,此时 Etag 可以更精确地判断资源是否变化。

7.3 缓存策略配置与优化

合理配置和优化 HTTP 缓存策略,可以进一步提升缓存的效果,提高网站或应用的性能和用户体验。以下是一些缓存策略配置与优化的建议:

  • 合理设置缓存过期时间:对于不经常更新的静态资源,如网站的 logo 图片、全局的 CSS 和 JavaScript 文件等,可以设置较长的缓存过期时间,例如将Cache-Control的max-age设置为一年(31536000 秒) ,这样可以减少用户多次访问时的请求次数,提高加载速度。对于可能会频繁更新的资源,如新闻文章页面、商品详情页等,要设置较短的缓存过期时间,以保证用户能够及时获取到最新的内容,比如设置max-age为几分钟或几小时。在设置缓存过期时间时,还需要考虑业务需求和数据的实时性要求,避免因为缓存时间过长导致数据过时,影响用户体验;也要避免缓存时间过短,导致缓存命中率过低,增加服务器负载和网络传输量。
  • 利用 CDN 缓存:CDN(内容分发网络)是一种分布式网络,通过在全球各地部署节点服务器,将缓存资源分发到离用户更近的边缘节点。当用户请求资源时,CDN 节点首先检查本地缓存,若命中则直接返回,否则从源服务器获取并缓存。利用 CDN 缓存可以进一步减少网络延迟和带宽消耗,提高访问速度。对于图片、视频、静态文件等资源,可以将其存储在 CDN 上,并合理设置 CDN 的缓存策略,如根据资源类型、访问频率等因素设置不同的缓存时间。一些 CDN 提供商还支持缓存预热功能,可以在网站流量高峰前,预先将热门资源缓存到 CDN 节点,提高缓存命中率和用户访问速度。
  • 版本控制与缓存更新:当资源更新时,为了确保用户能够获取到最新版本的资源,需要进行版本控制。一种常见的方法是在资源的 URL 中添加版本号或时间戳。例如,将 CSS 文件的 URL 从styles.css改为styles_v1.0.css,当 CSS 文件更新时,将版本号改为styles_v1.1.css,这样浏览器会认为这是一个新的资源,不会使用旧的缓存,而是重新向服务器请求。也可以使用文件指纹技术,如根据文件内容计算出 MD5、SHA - 1 等哈希值,将哈希值作为版本号添加到 URL 中,这样可以更精确地控制资源的版本,确保只有文件内容发生变化时才会更新版本号。在进行版本控制时,要注意及时更新相关的 HTML、JavaScript 等文件中对资源 URL 的引用,以保证页面能够正确加载最新的资源。
  • 缓存清理与失效策略:为了避免缓存中的数据过时或无效,需要制定合理的缓存清理与失效策略。可以设置缓存的过期时间,当缓存过期后,自动清理缓存数据。也可以根据业务需求,手动触发缓存失效。例如,在电商系统中,当商品信息发生更新时,通过后台管理系统发送缓存失效指令,清除与该商品相关的缓存数据,确保用户能够看到最新的商品信息。还可以使用缓存清理工具或脚本,定期清理缓存中长时间未使用的资源,释放缓存空间,提高缓存的利用率。
  • 结合使用强制缓存和协商缓存:在实际应用中,应根据资源的特点和更新频率,结合使用强制缓存和协商缓存。对于更新频率较低的资源,优先使用强制缓存,设置较长的缓存时间;对于更新频率较高但又需要一定缓存机制的资源,使用协商缓存,通过服务器验证来判断是否使用缓存,这样可以在保证数据及时性的同时,充分利用缓存提高性能。在设置缓存策略时,要注意避免缓存冲突和不一致的情况,确保缓存机制的正常运行。

八、实战应用与案例分析

8.1 使用工具抓包分析 HTTP 通信

在网络开发与调试过程中,深入了解 HTTP 通信过程是至关重要的,而使用工具进行抓包分析则是实现这一目标的有效手段。Wireshark 作为一款功能强大的开源网络封包分析软件,能够帮助我们直观地查看 HTTP 通信的细节,包括请求和响应的具体内容、数据传输的过程等。

使用 Wireshark 抓取 HTTP 数据包并进行分析,可参考以下步骤:

  1. 启动 Wireshark:打开 Wireshark 软件,它会显示当前计算机上可用的网络接口列表,选择需要进行抓包的网络接口,比如正在使用的以太网或 Wi-Fi 接口,点击 “开始捕获” 按钮,Wireshark 便开始捕获该接口上传输的所有网络数据包。
  2. 触发 HTTP 通信:在捕获数据包期间,在浏览器中访问目标网站或应用程序,执行一些会产生 HTTP 请求的操作,如加载网页、提交表单、点击链接等。这些操作所产生的 HTTP 请求和响应数据包都会被 Wireshark 捕获。
  3. 过滤 HTTP 数据包:由于网络中传输的数据包种类繁多,为了更方便地查看 HTTP 数据包,需要设置显示过滤器。在 Wireshark 的显示过滤器输入框中输入 “http”,然后按下回车键,此时 Wireshark 的数据包列表将只显示 HTTP 相关的数据包,其他非 HTTP 数据包将被过滤掉。如果想要进一步筛选特定网站或 IP 地址的 HTTP 数据包,可以使用 “http and ip.addr == 目标 IP 地址” 这样的过滤器表达式,例如 “http and ip.addr == 192.168.1.100”,这样就只会显示与该 IP 地址进行 HTTP 通信的数据包。
  4. 分析 HTTP 请求和响应:在 Wireshark 的数据包列表中,每一行代表一个捕获到的数据包。点击某个 HTTP 数据包,在下方的 “数据包详细信息” 窗格中可以查看该数据包的详细内容。对于 HTTP 请求数据包,可以看到请求行,包含请求方法(如 GET、POST 等)、请求的 URL 以及 HTTP 版本;请求头部分,包含各种信息,如 User - Agent(发起请求的客户端软件信息)、Host(目标服务器的域名和端口号)、Accept(客户端能够接收的响应内容类型)等;如果是 POST 请求,还可能包含请求体,即发送到服务器的数据。对于 HTTP 响应数据包,能看到状态行,包含 HTTP 版本、状态码(如 200 表示成功,404 表示未找到资源等)和状态消息;响应头部分,包含服务器信息(如 Server 字段)、内容类型(Content - Type)、内容长度(Content - Length)等;以及响应体,即服务器返回给客户端的实际数据,可能是 HTML 页面内容、JSON 数据等。
  5. 追踪 HTTP 流:为了更清晰地查看一次完整的 HTTP 通信过程,Wireshark 提供了 “追踪流” 功能。在数据包列表中右键点击某个 HTTP 数据包,选择 “追踪流”->“HTTP 流”,Wireshark 会将该 HTTP 通信过程中的所有请求和响应数据包整理在一起,以文本形式展示,方便查看整个通信流程和数据交互情况。例如,在追踪 HTTP 流中,可以看到客户端发送的请求内容以及服务器返回的响应内容,了解数据是如何在客户端和服务器之间传输的,以及服务器对请求的处理结果。

8.2 Web 开发中 HTTP 的应用案例

在 Web 开发领域,HTTP 协议贯穿于各个功能模块的实现过程中,下面结合常见的 Web 开发项目,深入分析登录、注册、数据请求等功能中 HTTP 的具体应用。

  1. 登录功能
    在用户登录功能的实现过程中,HTTP 协议发挥着核心作用。当用户在登录页面输入用户名和密码,并点击 “登录” 按钮时,浏览器会构建一个 HTTP 请求。通常情况下,这个请求会使用 POST 方法,以提高数据传输的安全性,因为 POST 方法将数据放置在请求体中,而非像 GET 方法那样暴露在 URL 中。请求的 URL 会指向服务器端处理登录逻辑的接口,比如 “/login” 。在请求头中,会包含 User - Agent 字段,用于标识客户端的浏览器类型和版本等信息,这有助于服务器进行一些兼容性处理;还会包含 Content - Type 字段,对于登录请求,常见的值为 “application/x-www-form-urlencoded” ,表示请求体中的数据是按照 URL 编码格式进行编码的,即 “key1=value1&key2=value2” 的形式。请求体中则会包含用户输入的用户名和密码,经过 URL 编码后发送到服务器。例如,用户名 “John” 和密码 “123456” ,在请求体中可能表示为 “username=John&password=123456” 。

服务器接收到登录请求后,会对请求进行解析。首先检查请求头,获取相关信息,然后从请求体中提取用户名和密码。接着,服务器会根据这些信息进行用户身份验证,通常是查询数据库,检查用户名和密码是否匹配。如果验证成功,服务器会返回一个包含用户身份信息的响应,比如生成一个会话 ID(Session ID),并将其通过 Set - Cookie 头设置到客户端的 Cookie 中,以便在后续请求中识别用户身份 。同时,响应状态码为 200,表示请求成功,响应体中可能包含一些用户相关的信息,如用户的基本资料、权限等 。如果验证失败,服务器会返回一个错误响应,状态码可能为 401 Unauthorized,表示未授权访问,响应体中会包含错误提示信息,如 “用户名或密码错误” ,告知用户登录失败的原因。

  1. 注册功能
    在用户注册功能的实现中,HTTP 同样扮演着关键角色。当用户在注册页面填写注册信息,如用户名、密码、邮箱等,并提交表单时,浏览器会发送一个 HTTP 请求到服务器。一般采用 POST 方法,以确保用户注册信息的安全性。请求的 URL 会指向服务器端负责处理注册逻辑的接口,例如 “/register” 。请求头中包含的信息与登录请求类似,User - Agent 用于标识客户端信息,Content - Type 通常为 “application/x-www-form-urlencoded” ,表明请求体的数据编码格式。请求体中则包含用户填写的各项注册信息,经过 URL 编码后发送给服务器 。例如,用户名 “Alice” 、密码 “abcdef” 、邮箱 “alice@example.com” ,在请求体中会表示为 “username=Alice&password=abcdef&email=alice@example.com” 。

服务器接收到注册请求后,首先解析请求头和请求体,获取用户注册信息。然后,服务器会进行一系列的验证和处理操作,包括检查用户名是否已被注册、密码强度是否符合要求、邮箱格式是否正确等 。如果所有验证都通过,服务器会将用户信息保存到数据库中,完成注册流程,并返回一个成功响应,状态码为 201 Created,表示资源已成功创建 。响应体中可能包含一些提示信息,如 “注册成功,请登录” 。如果验证过程中发现问题,服务器会返回相应的错误响应 。例如,如果用户名已被注册,状态码可能为 409 Conflict,表示冲突,响应体中包含错误提示 “用户名已存在,请重新输入” ;如果邮箱格式不正确,状态码可能为 400 Bad Request,表示请求错误,响应体中提示 “邮箱格式错误,请重新输入” 。

  1. 数据请求功能
    在 Web 应用中,经常需要从服务器获取各种数据,如新闻列表、商品信息等,这就涉及到 HTTP 的数据请求功能。以获取新闻列表为例,当用户打开新闻页面时,浏览器会向服务器发送一个 HTTP GET 请求 。请求的 URL 会包含一些参数,用于指定获取数据的条件,比如 “/news?category=tech&page=1” ,表示获取科技类新闻的第一页数据 。请求头中的 User - Agent 用于标识客户端,Accept 字段用于指定客户端能够接收的响应内容类型,常见的值如 “application/json” ,表示希望服务器返回 JSON 格式的数据。

服务器接收到数据请求后,根据 URL 中的参数查询数据库或其他数据源,获取相应的新闻数据 。然后,服务器将数据整理成客户端期望的格式(如 JSON),并返回给客户端 。响应状态码通常为 200,表示请求成功 。响应体中包含新闻列表数据,例如:

{"news": [{"title": "科技巨头发布最新产品","content": "某科技巨头今日发布了其最新的电子产品,具有多项创新功能...","date": "2024-06-15"},{"title": "人工智能领域新突破","content": "研究人员在人工智能领域取得了重大突破,该成果有望改变未来生活...","date": "2024-06-14"}],"total": 100,"page": 1,"per_page": 10
}

客户端接收到响应后,解析响应体中的数据,将新闻列表展示给用户 。如果服务器在处理请求过程中出现问题,比如数据库查询失败,会返回一个错误响应 。状态码可能为 500 Internal Server Error,表示服务器内部错误,响应体中包含错误信息,如 “数据库查询失败,请稍后重试” 。

九、总结与展望

9.1 HTTP 知识总结回顾

HTTP 作为互联网的核心应用层协议,是构建现代 Web 应用的基础,在网络通信中扮演着至关重要的角色。它基于客户端 - 服务器模式,采用请求 - 响应模型,使得客户端能够与服务器进行高效的数据交互。

从基础概念来看,HTTP 的报文结构清晰明了。请求报文包含请求行、请求头和请求正文,请求行指明请求方法、URL 和 HTTP 版本;请求头携带了关于客户端、请求内容等丰富的元信息;请求正文则承载了实际发送的数据(如 POST 请求中的表单数据)。响应报文同样由状态行、响应头和响应正文构成,状态行展示了 HTTP 版本、状态码及状态消息,直观地告知客户端请求的处理结果;响应头提供了服务器、响应内容等相关信息;响应正文则是服务器返回的实际资源数据。

HTTP 定义了多种请求方法,每种方法都有其特定的用途和语义。GET 方法常用于获取资源,以查询字符串形式将数据附加在 URL 后,简单方便,但不适合传输敏感数据且有长度限制;POST 方法主要用于提交数据,数据置于请求体中,更安全且理论上无长度限制,广泛应用于用户注册、表单提交等场景;PUT 方法用于更新资源,DELETE 方法用于删除资源,它们对服务器资源状态产生改变;HEAD 方法类似于 GET,但只返回头部信息,可用于获取资源元信息,减少数据传输量。同时,理解 HTTP 方法的幂等性和安全性对于正确使用这些方法至关重要,幂等性确保多次相同请求对资源影响一致,安全性则区分了对服务器资源有无副作用的请求方法。

HTTP 状态码是服务器与客户端沟通请求处理结果的重要方式,通过三位数字代码,将请求结果分为五类。1xx 信息性状态码表示临时响应,引导请求者后续操作;2xx 成功状态码表明请求顺利被服务器处理,如 200 OK 代表请求成功并返回资源;3xx 重定向状态码提示客户端进一步操作,通常是重定向到新 URL,像 301 Moved Permanently 表示资源永久移动,302 Found 表示临时移动;4xx 客户端错误状态码指出客户端请求存在问题,如 400 Bad Request 表示请求语法错误,404 Not Found 表示资源未找到;5xx 服务器错误状态码说明服务器处理请求时出现故障,如 500 Internal Server Error 表示服务器内部错误。

随着互联网发展,HTTP 也不断演进。HTTP/1.1 引入了持久连接、管道化、缓存控制、Host 头字段和分块传输编码等特性,显著提升了传输效率和功能,但存在队头阻塞、文本格式开销大、并发连接数量限制等不足。HTTP/2 则带来了二进制分帧、多路复用、头部压缩、服务器推送、流量控制和优先级设置等新特性,有效解决了 HTTP/1.1 的性能瓶颈,大幅提升了 Web 性能。HTTP/3 基于 UDP 协议的 QUIC 实现,具备 0 - RTT 握手、解决队头阻塞、连接迁移等优势,进一步优化了网络性能和用户体验。

安全方面,HTTP 存在窃听、篡改和冒充等风险,而 HTTPS 通过 SSL/TLS 协议进行加密通信、身份认证和数据完整性保护,有效解决了这些问题,实现了安全的网络通信。在缓存机制上,HTTP 缓存分为强制缓存和协商缓存,强制缓存通过 Cache-Control 和 Expires 字段控制缓存有效期,协商缓存则通过 Last-Modified/If-Modified-Since 和 Etag/If-None-Match 字段判断资源是否更新,合理配置缓存策略可减少网络传输、提高响应速度、降低服务器负载。

9.2 HTTP 未来发展趋势展望

在未来,随着网络技术的持续创新与发展,HTTP 协议有望在性能提升、安全性增强、应用场景拓展等方面实现重大突破。

在性能提升上,HTTP 协议会不断优化传输效率。随着网络带宽需求的不断增长以及用户对实时性体验要求的提高,HTTP 协议将进一步减少传输延迟,提升数据传输速度。例如,在 HTTP/3 的基础上,可能会进一步优化 QUIC 协议的拥塞控制算法,使其能够更智能地适应复杂多变的网络环境,从而更有效地利用网络带宽资源,减少数据传输的卡顿现象。并且,随着硬件技术的飞速发展,HTTP 协议也将与新硬件特性深度融合,充分发挥硬件的计算和处理能力,实现更高效的数据解析与传输,为用户提供更加流畅的网络访问体验。

安全性增强也是 HTTP 未来发展的关键方向。在当前网络安全形势日益严峻的背景下,用户对数据隐私和安全的关注度越来越高。HTTP 协议将持续强化安全机制,采用更先进的加密算法,进一步提高数据传输的保密性,防止数据在传输过程中被窃取或篡改。同时,在身份认证方面,会引入多因素认证等更严格、更安全的认证方式,确保通信双方身份的真实性和合法性,有效抵御各种网络攻击,保护用户的隐私和数据安全。

HTTP 的应用场景也将不断拓展。随着物联网(IoT)、边缘计算等新兴技术的迅速崛起,HTTP 协议将在这些领域发挥重要作用。在物联网场景中,大量的智能设备需要进行数据交互和通信,HTTP 协议凭借其简单易用、广泛支持的特点,将成为智能设备之间、智能设备与服务器之间数据传输的重要选择,实现智能家居、智能交通等各种物联网应用的互联互通。在边缘计算环境下,HTTP 协议能够支持在靠近数据源的边缘节点进行数据处理和传输,减少数据传输延迟,提高响应速度,为实时性要求较高的应用提供有力支持。

HTTP 协议还将与人工智能(AI)、大数据等技术深度融合,向智能化和个性化方向发展。借助 AI 技术,HTTP 协议可以实现更智能的请求路由和资源分配。例如,根据用户的历史行为数据和实时网络状况,智能地选择最优的服务器节点进行请求处理,提高服务质量和用户满意度。在大数据分析的支持下,HTTP 协议能够更好地理解用户需求,为用户提供更加个性化的内容和服务,实现用户与 Web 应用之间更深入、更精准的交互,推动 Web 应用向智能化、个性化的方向不断迈进。

http://www.xdnf.cn/news/1018855.html

相关文章:

  • @RequestHeader(“Authorization“) 解析:HTTP 请求头中的 Authorization 字段
  • JSON 编辑器:从语法到数据处理(二)
  • 在C#中乐观锁的实现
  • ios 26发布:设计革新与智能整合
  • 分析实例,学习了解浏览器事件循环机制
  • 基于ssm的教学质量评估系统
  • CIM和建筑风貌管控平台
  • [7-01-03].第03节:环境搭建 - 集群架构
  • Java企业技术趋势分析:AI应用的落地实践与未来展望
  • nuxt2报错Unexpected token ‘{‘
  • CSS flex-basis 属性详解:功能、用法与最佳实践
  • CSS Houdini 解锁前端动画的下一个时代!
  • 主流版本控制工具Git vs Perforce P4:架构模式、性能、大文件管理及分支管理对比详解
  • 在线教程丨刷新TTS模型SOTA,OpenAudio S1基于200万小时音频数据训练,深刻理解情感及语音细节
  • 引入 Kafka 消息队列解耦热点操作
  • list使用及模拟
  • HarmonyOS 应用模块化设计 - 面试核心知识点
  • WPF--Application.Current.Dispatcher.BeginInvoke
  • 在Jupyter Notebook中使用Conda虚拟环境
  • 使用 PyMuPDF 和 PySide6/PyQt6 编写的 PDF 查看器 (显示树状书签和缩略图列表,没有文字选择功能)
  • Monte Carlo衍生品定价(金融工程)
  • Spring Boot3流式访问Dify聊天助手接口
  • PHP语法基础篇(二):输出函数与字符串操作
  • 《第五章-心法进阶》 C++修炼生涯笔记(基础篇)指针与结构体⭐⭐⭐⭐⭐
  • 6月计算机新书:深度学习、大模型、DeepSeek
  • Blender 3D建模工具的快捷键总结--选择、视图、对象、编辑、UV贴图、模型材质、动画与渲染、工具
  • 238. 除自身以外数组的乘积
  • Linux运维-ansible-python开发-获取inventroy信息
  • 第二十五章 25.Network Architecture(CCNA)
  • 简析MDM在餐饮设备中的部署与应用