基于本文回答

HTTP原理详解

知识点图片

本文深入解析了HTTP协议,从基础报文到各版本演进,并解释了keep-alive长连接原理,以及HTTPS为保障安全与兼容而采用多种加密算法的原因。

这是一份非常详细的 HTTP 面试详解,旨在帮助你从容应对从初级到高级的各类面试问题。内容涵盖了 HTTP 的基础概念、核心组成、方法、状态码、版本演进以及与其相关的关键技术。


一、 什么是 HTTP?

HTTP (HyperText Transfer Protocol, 超文本传输协议) 是一个用于分布式、协作式和超媒体信息系统的应用层协议。简单来说,它就是客户端(通常是浏览器)和服务器之间请求和响应的规范。

核心特点:

  1. 简单快速:客户端向服务器请求服务时,只需传送请求方法和路径。
  2. 灵活:HTTP 允许传输任意类型的数据对象,通过 Content-Type 头部来标记。
  3. 无连接:每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。(这是 HTTP/1.0 的特点,HTTP/1.1 后引入了持久连接)。
  4. 无状态 (Stateless):协议对于事务处理没有记忆能力。即服务器不知道客户端上一次做了什么。这简化了服务器的设计,但为了处理需要登录等场景,引入了 Cookie 和 Session 机制来维持状态。

二、 HTTP 报文结构

HTTP 报文分为两种:请求报文 (Request) 和 响应报文 (Response)。

1. 请求报文 (Request)

由三部分组成:请求行、请求头、请求体。

plaintext
<method> <request-url> <http-version>  // 请求行 (Request Line)
<headers>                             // 请求头 (Request Headers)
                                      // 空行 (CRLF)
<body>                                // 请求体 (Request Body)
  • 请求行 (Request Line)
    • 方法 (Method):如 GET, POST, PUT 等。
    • URL:请求的资源路径。
    • 协议版本:如 HTTP/1.1。
  • 请求头 (Request Headers):Key: Value 格式的键值对,用于传递附加信息。
    • Host: 指定服务器的域名(HTTP/1.1 必须)。
    • User-Agent: 客户端(浏览器)信息。
    • Accept: 客户端可接收的内容类型。
    • Content-Type: 请求体的媒体类型(如 application/json)。
    • Authorization: 用于身份验证的凭证。
    • Cookie: 客户端携带的 Cookie。
  • 请求体 (Request Body):可选。通常用于 POST, PUT 等请求,存放要提交给服务器的数据。GET 请求没有请求体。

2. 响应报文 (Response)

由三部分组成:状态行、响应头、响应体。

plaintext
<http-version> <status-code> <status-text>  // 状态行 (Status Line)
<headers>                                  // 响应头 (Response Headers)
                                           // 空行 (CRLF)
<body>                                     // 响应体 (Response Body)
  • 状态行 (Status Line)
    • 协议版本:如 HTTP/1.1。
    • 状态码 (Status Code):如 200, 404。
    • 状态文本 (Status Text):对状态码的简要描述,如 OK, Not Found。
  • 响应头 (Response Headers):Key: Value 格式。
    • Content-Type: 响应体的媒体类型(如 text/html, application/json)。
    • Content-Length: 响应体的长度。
    • Set-Cookie: 服务器向客户端设置 Cookie。
    • Cache-Control: 控制缓存策略。
    • Access-Control-Allow-Origin: 用于 CORS(跨域资源共享)。
  • 响应体 (Response Body):服务器返回给客户端的实际数据,如 HTML 页面、JSON 数据、图片等。

三、 常见的 HTTP 方法 (Methods)

方法 描述 安全性 (Safe) 幂等性 (Idempotent)
GET 获取资源。 是 是
POST 创建或提交数据,通常会导致资源状态改变。 否 否
PUT 替换整个资源或创建指定 URI 的资源。 否 是
DELETE 删除资源。 否 是
PATCH 对资源进行部分修改。 否 否
HEAD 类似 GET,但只返回响应头,不返回响应体。 是 是
OPTIONS 获取目标资源所支持的通信选项(如允许的方法)。 是 是
  • 安全性 (Safe):指该操作不会改变服务器上的资源状态。GET, HEAD 是安全的。
  • 幂等性 (Idempotent):指一次和多次请求某一个资源应该具有同样的副作用。GET, PUT, DELETE 是幂等的。POST 不是,多次提交会创建多个资源。

面试题:POST 和 PUT 的区别?

  • POST:主要用于创建资源,不具有幂等性。每次请求都可能在服务器上创建一个新的资源。
  • PUT:主要用于更新/替换资源,具有幂等性。如果资源存在,则替换;如果不存在,则创建。多次发送同一个 PUT 请求,结果是相同的。

四、 常见的 HTTP 状态码 (Status Codes)

状态码由三位数字组成,分为五类:

  • 1xx (信息性):表示请求已接收,继续处理。
    • 101 Switching Protocols:在 WebSocket 握手时常见。
  • 2xx (成功):表示请求已成功被服务器接收、理解、并接受。
    • 200 OK:请求成功。
    • 201 Created:请求成功并且服务器创建了新的资源(如 POST 请求后)。
    • 204 No Content:请求成功,但没有响应体(如 DELETE 请求后)。
  • 3xx (重定向):表示要完成请求,需要进一步操作。
    • 301 Moved Permanently:永久重定向。浏览器会缓存这个地址。
    • 302 Found:临时重定向。
    • 304 Not Modified:协商缓存命中,告诉客户端可以使用本地缓存。
  • 4xx (客户端错误):表示请求包含语法错误或无法完成请求。
    • 400 Bad Request:请求语法错误。
    • 401 Unauthorized:请求需要用户认证。
    • 403 Forbidden:服务器拒绝执行请求(权限不足)。
    • 404 Not Found:服务器找不到请求的资源。
    • 405 Method Not Allowed:请求方法不被允许。
  • 5xx (服务器错误):表示服务器在处理请求的过程中发生了错误。
    • 500 Internal Server Error:服务器内部错误。
    • 502 Bad Gateway:作为网关或代理的服务器,从上游服务器收到无效响应。
    • 503 Service Unavailable:服务器暂时无法处理请求(过载或维护)。
    • 504 Gateway Timeout:网关或代理未及时从上游服务器获得响应。

五、 HTTP 版本演进 (非常重要)

HTTP/1.0

  • 短连接:每个请求/响应都建立一个新的 TCP 连接,完成后立即断开,开销很大。
  • 无 Host 头部,导致一台服务器只能托管一个域名。

HTTP/1.1 (目前最广泛使用)

  • 长连接 (Persistent Connections):默认开启 Connection: keep-alive,一个 TCP 连接可以复用发送多个请求。
  • 管道化 (Pipelining):允许在一个 TCP 连接上,客户端可以连续发送多个请求,而不用等待前一个请求的响应。但响应必须按请求顺序返回,如果第一个响应阻塞,后面的都会被阻塞,这叫队头阻塞 (Head-of-Line Blocking, HOL)。
  • 强制 Host 头部:支持虚拟主机,即一台服务器可以托管多个域名。
  • 更丰富的缓存控制:引入 Cache-Control 头部。
  • 新增了方法:PUT, DELETE, PATCH 等。

HTTP/2

  • 二进制分帧 (Binary Framing):将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式编码。解析效率更高,更不易出错。
  • 多路复用 (Multiplexing):核心改进。在一个 TCP 连接上,可以同时发送和接收多个请求/响应,并且不按顺序。解决了 HTTP/1.1 的队头阻塞问题。
  • 头部压缩 (Header Compression):使用 HPACK 算法压缩头部,减少请求大小。
  • 服务器推送 (Server Push):服务器可以主动向客户端推送资源,而无需客户端明确请求。

HTTP/3

  • 基于 QUIC 协议:HTTP/3 的底层支撑协议从 TCP 换成了 QUIC (Quick UDP Internet Connections)。
  • QUIC 是基于 UDP 的。为什么?因为 TCP 本身也存在队头阻塞问题。如果一个 TCP 数据包丢失,后续的数据包即使已经到达,也必须等待重传,这会阻塞该连接上的所有 HTTP/2 的流。
  • 解决了 TCP 的队头阻塞:QUIC 的流是独立的,一个流的丢包不会影响其他流。
  • 更快的连接建立:QUIC 实现了 0-RTT 或 1-RTT 的连接建立,减少了握手延迟。
  • 连接迁移 (Connection Migration):当客户端网络变化(如从 Wi-Fi 切换到 4G),TCP 连接会中断,而 QUIC 可以保持连接不中断,无缝迁移。

六、 相关重要概念

1. HTTPS

  • 是什么:HTTPS = HTTP + SSL/TLS。它在 HTTP 的基础上,通过 SSL/TLS 协议对数据进行加密传输。
  • 作用:
    • 加密 (Encryption):防止数据在传输过程中被窃听。
    • 完整性 (Integrity):防止数据被篡改。
    • 认证 (Authentication):通过证书验证服务器(或客户端)的身份。
  • TLS 握手过程简述:
    1. 客户端发送 ClientHello,包含支持的协议版本、加密套件、一个随机数。
    2. 服务器响应 ServerHello,确定使用的协议和加密套件,并附上自己的数字证书和一个随机数。
    3. 客户端验证证书的有效性,然后生成一个新的随机数(预主密钥),并用证书中的公钥加密后发送给服务器。
    4. 服务器用自己的私钥解密,得到预主密钥。
    5. 双方根据三个随机数共同生成会话密钥(对称密钥)。
    6. 之后的数据通信都使用这个会话密钥进行对称加密。

2. 无状态与 Cookie/Session

  • 无状态:服务器不保存客户端的任何状态信息。
  • Cookie:服务器通过 Set-Cookie 响应头发送给客户端的一小段数据。浏览器会保存它,并在之后对该服务器的每次请求中都通过 Cookie 请求头带上它。存储在客户端。
  • Session:一种服务器端的机制。服务器为每个用户创建一个 Session 对象,存储用户相关信息。它通过一个唯一的 session_id 来标识。这个 session_id通常会通过 Cookie 发送给客户端。客户端后续请求只需带上 session_id,服务器就能找到对应的 Session 数据。存储在服务器端。

3. HTTP 缓存

缓存是提升性能的重要手段。分为强缓存和协商缓存。

  • 强缓存:浏览器不向服务器发送请求,直接从本地缓存读取资源。
    • Cache-Control: max-age=3600:响应头中设置,表示资源在 3600 秒内有效。
    • Expires:HTTP/1.0 的字段,表示缓存过期的绝对时间。优先级低于 Cache-Control。
  • 协商缓存:强缓存失效后,浏览器向服务器发送请求,服务器根据资源是否有更新来决定是返回新资源(200 OK)还是让浏览器用本地缓存(304 Not Modified)。
    • Last-Modified / If-Modified-Since:
      1. 服务器在响应头中返回 Last-Modified(资源最后修改时间)。
      2. 浏览器再次请求时,在请求头中带上 If-Modified-Since,值为上次的 Last-Modified。
      3. 服务器比较时间,如果未变,返回 304。
    • ETag / If-None-Match:
      1. 服务器返回 ETag(资源的唯一标识符,如内容的 Hash 值)。
      2. 浏览器再次请求时,带上 If-None-Match,值为上次的 ETag。
      3. 服务器比较 ETag,如果未变,返回 304。ETag比Last-Modified更精确。

七、 经典面试题串讲

问:从浏览器地址栏输入 URL 到页面展示,发生了什么?

这是考察网络知识的终极问题,可以把以上所有知识点串联起来。

  1. URL 解析:浏览器解析 URL,判断协议、域名、端口、路径等。
  2. DNS 查询:浏览器查询 DNS,获取域名对应的 IP 地址。(中间涉及浏览器缓存、系统缓存、路由器缓存、ISP DNS 服务器、根服务器等)。
  3. 建立 TCP 连接:浏览器与服务器通过 IP 地址和端口号建立 TCP 连接(三次握手)。
  4. 发起 HTTP(S) 请求:
    • 如果是 HTTPS,先进行 TLS 握手,协商加密密钥。
    • 浏览器构建 HTTP 请求报文(请求行、请求头、请求体),通过 TCP 连接发送给服务器。
  5. 服务器处理请求:服务器接收并解析请求报文,根据路径和参数执行相应的逻辑(如查询数据库、调用 API),然后构建 HTTP 响应报文。
  6. 返回 HTTP 响应:服务器将响应报文发送回浏览器。
  7. 关闭 TCP 连接:根据 Connection 头部决定是否关闭连接(HTTP/1.1 默认不关闭)。
  8. 浏览器解析渲染页面:
    • 浏览器解析响应报文,首先解析 HTML,构建 DOM 树。
    • 解析 CSS,构建 CSSOM 树。
    • 将 DOM 和 CSSOM 合并成渲染树 (Render Tree)。
    • 根据渲染树进行布局 (Layout) 和绘制 (Paint)。
    • 在解析过程中,如果遇到 JS、图片、CSS 等外部资源,会重复上述步骤(DNS查询、TCP连接、HTTP请求等)去加载这些资源。

希望这份详尽的指南能帮助你在面试中脱颖而出!

右滑查看面试常问