HTTP 协议
HTTP (HyperText Transfer Protocol,超文本传输协议) 是互联网上应用最广泛的一种网络协议,是构建万维网(World Wide Web)数据通信的基础。它是一个客户端(通常是浏览器)和服务器端(通常是网站)之间请求和应答的标准。
1. 核心特点
- 简单快速:客户端向服务器请求服务时,只需传送请求方法和路径。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
- 灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由
Content-Type加以标记。 - 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。(HTTP/1.1 后支持持久连接)。
- 无状态 (Stateless):HTTP 协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传。这也使得服务器不需要先前的信息,可以更快地响应。为了解决这个问题,Web 应用通常使用 Cookies 和 Sessions 来维持状态。
2. HTTP 报文结构 (Message Structure)
HTTP 报文是服务器和客户端之间交换数据的方式,分为两种:请求报文 (Request Message) 和 响应报文 (Response Message)。
2.1 请求报文
由客户端发送给服务器。
http
<Method> <Request-URI> <HTTP-Version> (请求行)
<Headers> (请求头)
<CRLF> (空行)
<Request-Body> (请求正文)- 请求行 (Request Line):
- Method: 请求方法,如
GET、POST。 - Request-URI: 请求的资源标识符(URL)。
- HTTP-Version: 协议版本,如
HTTP/1.1。 - 示例:
GET /index.html HTTP/1.1
- Method: 请求方法,如
- 请求头 (Headers):用键值对的形式,向服务器传递客户端的信息、请求的附加信息等。
- 示例:
Host: www.example.com,User-Agent: Chrome/90.0...
- 示例:
- 空行 (CRLF):一个回车换行符,用于分隔请求头和请求正文。
- 请求正文 (Body):可选。当使用
POST,PUT等方法时,客户端要发送给服务器的数据。
2.2 响应报文
由服务器返回给客户端。
http
<HTTP-Version> <Status-Code> <Reason-Phrase> (状态行)
<Headers> (响应头)
<CRLF> (空行)
<Response-Body> (响应正文)- 状态行 (Status Line):
- HTTP-Version: 协议版本。
- Status-Code: 状态码,如
200、404。 - Reason-Phrase: 对状态码的简短文本描述,如
OK、Not Found。 - 示例:
HTTP/1.1 200 OK
- 响应头 (Headers):用键值对的形式,传递服务器自身的信息、对响应的附加信息。
- 示例:
Content-Type: text/html,Content-Length: 1234
- 示例:
- 空行 (CRLF):分隔响应头和响应正文。
- 响应正文 (Body):服务器返回给客户端的实际数据,如 HTML 页面、JSON 数据、图片等。
3. HTTP 请求方法 (Methods)
HTTP 定义了一组请求方法,以表明要对给定资源执行的操作。
| 方法 | 描述 | 特性 |
|---|---|---|
GET | 获取资源。 | 安全、幂等、可缓存 |
POST | 提交数据,导致服务器状态的改变或副作用(如创建新资源)。 | 不安全、不幂等、不可缓存 |
PUT | 替换目标资源的所有当前表示。 | 不安全、幂等 |
DELETE | 删除指定的资源。 | 不安全、幂等 |
PATCH | 对资源进行部分修改。 | 不安全、不幂等 |
HEAD | 与GET方法相同,但服务器在响应中只返回头部,不返回实体部分。用于检查资源是否存在或获取元数据。 | 安全、幂等、可缓存 |
OPTIONS | 返回服务器针对特定资源所支持的 HTTP 请求方法。 | 安全、幂等 |
- 安全性 (Safe): 指该操作不会改变服务器的状态(只读)。
- 幂等性 (Idempotent): 指多次执行同样的操作,产生的影响是相同的。
4. HTTP 状态码 (Status Codes)
状态码由三位数字构成,第一个数字定义了响应的类别。
| 分类 | 类别 | 描述 |
|---|---|---|
| 1xx | 信息性 (Informational) | 表示请求已接收,继续处理。 |
| 2xx | 成功 (Success) | 表示请求已被成功接收、理解、接受。 |
| 3xx | 重定向 (Redirection) | 要完成请求,需要采取进一步操作。 |
| 4xx | 客户端错误 (Client Error) | 请求有语法错误或请求无法实现。 |
| 5xx | 服务器错误 (Server Error) | 服务器未能实现合法的请求。 |
常见状态码:
| 状态码 | 含义 |
|---|---|
200 OK | 请求成功。 |
201 Created | 请求成功并且服务器创建了新的资源。 |
301 Moved Permanently | 永久重定向,请求的资源已永久移动到新位置。 |
302 Found | 临时重定向。 |
400 Bad Request | 客户端请求有语法错误,不能被服务器理解。 |
401 Unauthorized | 请求未经授权,需要用户验证。 |
403 Forbidden | 服务器收到请求,但是拒绝提供服务。(权限不足) |
404 Not Found | 请求的资源不存在。 |
500 Internal Server Error | 服务器内部发生了不可预期的错误。 |
502 Bad Gateway | 作为网关或代理的服务器,从上游服务器收到无效响应。 |
503 Service Unavailable | 服务器当前不能处理请求(由于超载或停机维护)。 |
5. 常见问题 (FAQ)
5.1 HTTP 和 HTTPS 有什么区别?
主要区别在于安全性。
- HTTP: 超文本传输协议,数据以明文方式发送,不安全。默认端口
80。 - HTTPS: 安全套接字层超文本传输协议(HTTP over SSL/TLS),可以理解为“HTTP 的安全版”。它在 HTTP 之下增加了 SSL/TLS 协议层,对所有数据进行加密传输,确保了数据的机密性、完整性和身份验证。默认端口
443。
5.2 HTTP 是无状态的,那网站如何“记住”我?(Cookies 和 Sessions)
通过 Cookies 和 Sessions 技术。
- 服务器创建 Session: 当你第一次访问网站(如登录),服务器会为你创建一个唯一的 Session ID,并把你的登录状态等信息存储在服务器上与这个 ID 关联。
- 服务器下发 Cookie: 服务器通过响应头中的
Set-Cookie,将这个 Session ID 发送给你的浏览器。 - 浏览器存储 Cookie: 浏览器会自动存储这个 Cookie(包含 Session ID)。
- 后续请求携带 Cookie: 之后你对该网站的每一次请求,浏览器都会自动通过
Cookie请求头,把这个 Session ID 带上。 - 服务器验证状态: 服务器收到请求后,从 Cookie 中读取 Session ID,找到对应的 Session 数据,就知道你是谁、你的登录状态如何了。
5.3 GET 和 POST 请求有什么主要区别?
这是面试高频题。
| 特性 | GET | POST |
|---|---|---|
| 数据位置 | 参数附加在 URL 后面,以 ? 分隔。 | 数据放在请求正文(Request Body)中。 |
| 安全性 | 不安全,因为数据暴露在 URL 中。 | 相对安全,数据不会显示在 URL 中。 |
| 幂等性 | 幂等。 | 不幂等,多次提交会创建多个资源。 |
| 可缓存 | 可被浏览器缓存。 | 默认不可缓存。 |
| 数据大小 | URL 长度有限制(不同浏览器和服务器限制不同)。 | 理论上无限制。 |
| 用途 | 通常用于获取或查询数据。 | 通常用于提交或创建数据。 |
5.4 什么是 RESTful API?它和 HTTP 是什么关系?
- REST (Representational State Transfer) 是一种软件架构风格,不是一种协议。它提倡用一种清晰、统一的方式来设计网络应用。RESTful API 就是遵循 REST 风格设计的 API。
- 关系:REST 利用 HTTP 协议来工作。它充分利用了 HTTP 的方法(
GET,POST,PUT,DELETE)来表达对资源的增删改查 (CRUD) 操作,使得 API 具有清晰的语义。GET /users:获取用户列表POST /users:创建一个新用户PUT /users/123:替换 ID 为 123 的用户信息DELETE /users/123:删除 ID 为 123 的用户
5.5 HTTP/1.0, HTTP/1.1, HTTP/2, HTTP/3 的主要区别是什么?
这是一个不断演进的过程,旨在让 Web 更快。
- HTTP/1.0 (1996): 最基础的版本,每个 TCP 连接只能发送一个请求,完成后立即关闭。
- HTTP/1.1 (1999): 引入了持久连接 (Keep-Alive),一个 TCP 连接可以复用发送多个请求,避免了频繁建连的开销。但存在队头阻塞 (Head-of-line blocking) 问题,即一个请求阻塞了,后续请求必须等待。
- HTTP/2 (2015): 这是一个重大升级。
- 二进制协议: 不再是纯文本,解析效率更高。
- 多路复用 (Multiplexing): 在一个 TCP 连接上,可以同时发送和接收多个请求/响应,彻底解决了队头阻塞问题。
- 头部压缩 (HPACK): 压缩请求和响应的头部,减少传输体积。
- HTTP/3 (2022): 更进一步的革命。
- 基于 QUIC 协议: QUIC 是基于 UDP 的,而不是 TCP。
- 解决了传输层队头阻塞: HTTP/2 只解决了应用层的队头阻塞,但如果底层 TCP 发生丢包,整个连接还是会卡住。QUIC 在 UDP 之上实现了可靠传输,一个流的丢包不会影响其他流,解决了这个问题。