HTTP 基础知识

HTTP(超文本传输协议)是
网络上的交流。

HTTP 的核心基于两个基本思想:

  1. 无状态模型
  2. 客户端-服务器模型

1.无状态模型

HTTP 遵循 无状态 通信模型。

无状态意味着服务器不记得
之前与客户的任何互动。
每个 HTTP 请求都被视为一个全新的请求。

无状态意味着什么?

  • 每个请求都包含所有必需的信息
  • 信息通过以下方式发送:
    • 标题
    • 网址
    • 方法(GET、POST 等)
    • 身体(如果需要)
  • 一旦服务器发送响应,它就会丢弃该请求
  • 下一个请求被认为是独立的

换句话说,HTTP 请求是独立的

无状态模型的好处

1. 简单

无状态系统更容易设计和维护
因为服务器不需要存储客户端会话数据。

2. 可扩展性

由于服务器上没有存储会话状态,
请求可以分布在多个服务器上
使用负载平衡器。

3. 可靠性

如果一台服务器出现故障,另一台服务器可以处理请求
而不丢失会话数据。

4. 状态管理的灵活性

虽然HTTP本身是无状态的,
应用程序可以使用以下方式保持连续性:

  • 饼干
  • 会议
  • 令牌(JWT、OAuth)

这些机制构建于HTTP之上
不是 HTTP 本身的一部分。

2. 客户端-服务器模型

HTTP 遵循客户端-服务器架构

在典型的 HTTP 交互中:

  • 客户端发起通信
  • 服务器响应请求

客户的责任

客户端(浏览器、移动应用程序或其他服务):

  • 发起请求
  • 发送所需数据,例如:
    • 网址
    • 标题
    • HTTP方法
    • 请求正文(如果适用)

服务器职责

服务器:

  • 托管资源,例如:
    • 网页
    • API
    • 文件
  • 等待传入的请求
  • 处理请求
  • 发送适当的响应,例如:
    • HTML 页面
    • JSON数据
    • 文件
    • 状态代码

根据HTTP协议,
通信始终由客户端发起

HTTP 与 HTTPS

HTTP 和 HTTPS 遵循相同的协议规则。

区别在于安全性。

  • HTTP 以纯文本形式发送数据
  • HTTPS 使用 TLS/SSL 加密数据

HTTPS 确保:

  • 数据保密性
  • 数据完整性
  • 服务器真实性

在生产系统中,
HTTPS 是强制的。

传输层和连接

对于客户端发送请求或接收响应,
需要网络连接。

HTTP 在传输层使用 TCP 协议。

TCP(传输控制协议)

TCP 是一种传输协议,它提供:

  • 可靠的数据传输
  • 订购的数据包
  • 错误检查和重传

由于这些保证,
TCP 被认为比其他传输协议更可靠。

TCP 与 UDP

有两种主要的传输协议:

  • TCP(传输控制协议)
  • UDP(用户数据报协议)

TCP 可靠但速度稍慢。
UDP 速度更快,但不能保证传送。

传统的 HTTP 使用 TCP。
(一些现代协议(例如 HTTP/3)使用 QUIC over UDP。)

OSI 模型概述

网络通信通俗解释
使用 OSI(开放系统互连)模型。

OSI模型由7层组成:

  1. 身体方面
  2. 数据链
  3. 网络
  4. 交通
  5. 会议
  6. 演示
    七、申请

后端工程师的视角

作为后端工程师,我们主要从事:

  • 第 7 层:应用层

这包括:

  • 设计API
  • 处理HTTP请求和响应
  • 实现身份验证和授权
  • 管理数据格式(JSON、XML)
  • 返回适当的状态代码

然而,了解较低层
帮助调试性能、网络、
和生产问题。

HTTP 的演变

HTTP(超文本传输协议)随着时间的推移而发展
提高性能、可靠性和可扩展性
随着网络变得越来越复杂。

本文档解释了主要的 HTTP 版本
以及它们的优点和局限性。

HTTP/0.9 (1991)

HTTP 的第一个也是最简单的版本。

优点: 极其简单和轻量级,适合早期基于文本的网络通信。
缺点: 仅支持 GET 请求、纯文本响应,并且没有标头、状态代码或元数据。

HTTP/1.0 (1996)

引入了 HTTP 通信的结构和元数据。

优点: 添加了请求/响应标头、状态代码以及对不同内容类型的支持。
缺点: 为每个请求打开一个新的 TCP 连接,导致高延迟和性能差。

HTTP/1.1 (1997)

成为网络通信的长期标准。

优点: 引入了持久连接和请求管道,减少了连接开销。
缺点: 由于顺序请求处理,仍然遭受队头阻塞。

HTTP/2 (2015)

旨在显着提高性能和效率。

优点: 启用多路复用、二进制成帧和标头压缩,大大提高速度。
缺点: 基于 TCP 构建,因此数据包丢失可能会阻塞所有流(TCP 级队头阻塞)。

HTTP/3 (2022)

针对现代网络优化的最新版本。

优点: 在 UDP 上使用 QUIC,消除 TCP 队头阻塞并提高不可靠网络上的性能。
缺点: 实施起来更复杂,并且并非所有遗留系统都完全支持。

HTTP 消息

有两种类型的消息 - 请求消息和响应消息

(1)请求消息——这是客户端发送的消息
(2)响应消息——这是服务器发送给客户端的消息

1. HTTP 请求消息

客户端发送HTTP请求消息
(浏览器、移动应用程序或其他服务)
请求资源或在服务器上执行操作。

HTTP 请求的结构

每个 HTTP 请求消息包含:

  • HTTP 方法
  • 资源(URL/路径)
  • HTTP 版本
  • 标题
  • 请求正文(可选)

完整的 HTTP 请求示例

POST /login HTTP/1.1 # 方法、资源、HTTP 版本
主机:example.com
用户代理:Mozilla/5.0
内容类型:application/json
授权:持有者 # 标头

{
“用户名”:“john_doe”,
“密码”:“123456”
} # 请求正文

2. HTTP 响应消息

服务器发送 HTTP 响应消息
处理完客户的请求后。

HTTP 响应的结构

每个 HTTP 响应消息包含:

  • HTTP 版本
  • 状态代码
  • 状态消息
  • 标题
  • 响应正文(可选)

完整的 HTTP 响应示例

HTTP/1.1 200 OK # HTTP 版本、状态代码、状态消息
内容类型:application/json
内容长度:128
日期:2026 年 1 月 16 日星期二 10:30:00 GMT
服务器:nginx # 标头

{
“成功”:真实,
“message”: “用户获取成功”,
“数据”:{
“id”:101,
“用户名”:“john_doe”,
“电子邮件”:“john@example.com
}
} # 响应正文

重要提示

  • 请求消息总是由客户端发起
  • 响应消息始终由服务器发送
  • 标头携带有关消息的元数据
  • 正文包含实际数据(JSON、HTML、文本、文件)
  • 正文是可选的,取决于 HTTP 方法和状态代码

为什么我们需要标题?

出现一个常见问题:
为什么我们有一个名为 标题 的单独部分?
为什么不发送 URLpathbody 中的所有内容?

简单说明

标头的存在是为了携带有关请求或响应的元数据

它们描述了“如何”处理数据,
不是实际数据什么

现实生活中的类比(快递示例)

将 HTTP 想象成发送快递包裹。

当发件人发送包裹时:

  • 地址发件人详细信息处理说明
    包装上写有
  • 快递员没有打开包裹
    查找此信息

如果所有细节都保留在包装内,
每次快递员都要打开它,
这是低效且不安全的。

这如何应用于 HTTP

在 HTTP 中同样如此:

  • 标题就像写在包裹上的信息
  • 正文就像包装内的内容

标头允许服务器、代理和浏览器:

  • 识别发件人
  • 了解内容类型
  • 检查身份验证
  • 应用缓存规则
  • 执行安全政策

所有这一切都是在不读取请求正文的情况下发生的

为什么不在正文或 URL 中放入标头?

将所有内容放入正文或 URL 中会导致问题:

  • 服务器需要解析每个请求的正文
  • 代理和缓存无法有效工作
  • 安全检查将变得更加困难
  • 大型物体会减慢处理速度

标头通过保留重要的控制信息来解决这个问题
独立且轻便。

不同类型的 HTTP 标头

HTTP 标头是与请求或响应一起发送的元数据
它们就像一个遥控器,告诉服务器或客户端
如何处理消息。

标头分为四种主要类型:

  1. 请求头
  2. 通用标题
  3. 表示标头
  4. 安全标头

1. 请求头

请求标头帮助服务器了解客户端的环境、偏好和功能。

(1) 用户代理 - 标识发出请求的客户端软件(浏览器、应用程序或设备)。
(2)Authorization - 包含用于身份验证的凭据(令牌、API 密钥等)。
(3)Cookie - 将存储的cookie从客户端发送到服务器。
(4)Accept - 指定客户端可以处理的媒体类型(JSON、HTML、XML、e

2. 通用标题

通用标头可用于请求和响应中。

(1)日期 - 指定发送消息的日期和时间。
(2)Cache-Control - 指导缓存行为(例如,公共、私有、无缓存)。
(3)Connection - 控制连接在消息后是保持打开状态还是关闭。

3. 表示标头

表示标头描述消息正文的格式和编码。

标头
(1)Content-Type - 指定正文的 MIME 类型(例如 application/json)。
(2)Content-Length - 指示主体的大小(以字节为单位)。
(3)Content-Encoding - 指定在正文上使用的任何压缩(gzip、deflate)。
(4)ETag - 为特定版本的资源提供唯一标识符(用于缓存)。

4. 安全标头

安全标头增强了请求和响应的安全性。

标头
(1) 严格传输安全 (HSTS) - 强制客户端对未来的请求使用 HTTPS。
(2)Content-Security-Policy (CSP) - 定义允许加载哪些资源,防止XSS攻击。
(3)X-Frame-Options - 通过控制页面是否可以嵌入框架来防止点击劫持。
(4)X-Content-Type-Options - 阻止浏览器进行 MIME 类型嗅探以防止攻击。
(5)Set-Cookie - 将带有可选安全标志的 cookie 从服务器发送到客户端。

HTTP 方法

存在 Http 方法来表示客户端可以在服务器上请求的不同类型的操作。

HTTP 方法

(1) GET——用于服务器的响应
(2) POST - 用于将数据从客户端发送到服务器
(3) PUT——用于替换或更新完整数据
(4)PATCH——用于更新数据的特定部分
(5)DELETE——用于删除

HTTP 方法

HTTP 方法定义客户端希望服务器对资源执行的操作类型
它们也称为动词,对于 RESTful API 设计至关重要。


常见的 HTTP 方法

方法 描述
获取 从服务器请求数据而不修改它。
发布 将数据从客户端发送到服务器以创建新资源。
放置 用新数据替换或更新完整资源。
补丁 更新资源的特定部分而不替换整个资源。
删除 删除服务器上的指定资源。

重要提示

  • HTTP 方法是 幂等 如果重复它们具有相同的效果:
    • 获取、放置、删除 → 幂等
    • POST、PATCH → 通常不是幂等的
  • 选择正确的方法对于 API 设计、缓存和安全性很重要。
  • 方法区分大小写并且通常以大写编写。

用法示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# GET request
GET /users/101 HTTP/1.1
Host: example.com

# POST request
POST /users HTTP/1.1
Host: example.com
Content-Type: application/json

{
"username": "john_doe",
"email": "john@example.com"
}

# PATCH request
PATCH /users/101 HTTP/1.1
Host: example.com
Content-Type: application/json

{
"email": "new_email@example.com"
}

# DELETE request
DELETE /users/101 HTTP/1.1
Host: example.com

OPTIONS 方法和 CORS 流程

OPTIONS HTTP 方法在 CORS(跨源资源共享) 流程中起着关键作用。

CORS 是一种浏览器安全机制,用于控制如何从不同来源(域、协议或端口)请求 Web 服务器上的资源。它使用 HTTP 标头显式允许或限制跨源请求,从而防止对敏感数据进行未经授权的访问。在生产环境中,正确的 CORS 配置对于平衡安全性和合法的跨域通信至关重要。


CORS 请求流的类型

两种类型的 CORS 请求流

  1. 简单的请求
  2. 预检请求

1. 简单的请求流程

假设:

  • 前端(客户端)托管在 https://example.com
  • 后端(服务器)托管在 https://api.example.com

客户端请求(简单 GET 请求)

1
2
3
4
5
GET /api/products/123 HTTP/1.1
Host: api.example.com
Origin: https://example.com

Accept: application/json

服务器行为

  • 服务器检查是否允许 Origin
  • 如果允许,它会在响应中包含 Access-Control-Allow-Origin 标头。

服务器响应

1
2
3
4
5
6
7
8
9
10
HTTP/1.1 200 OK
Content-Type: application/json
Access-Control-Allow-Origin: https://example.com

{
"product": {
"id": 123,
"name": "xyz"
}
}

重要提示

  • 浏览器允许访问响应仅当
    • Access-Control-Allow-Origin 与请求来源匹配,或者
    • 使用 Access-Control-Allow-Origin: * (不建议用于经过身份验证的数据或敏感数据)。
  • 如果没有此标头,即使服务器返回数据,浏览器也会阻止响应。

2. 预检请求流程

当满足以下任何条件时,请求将成为“预检”:

  • HTTP 方法不是 GETPOSTHEAD(例如,PUTDELETE
  • 请求包含非简单标头(例如,AuthorizationX-Custom-Header
  • Content-Type 不是以下之一:
    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

在这些情况下,浏览器在发出实际请求之前,会使用 OPTIONS 方法发送 预检请求


预检请求(选项)

1
2
3
4
5
6
OPTIONS /api/users HTTP/1.1
Host: api.example.com
Origin: https://frontend.example.com

Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, Authorization

服务器对预检的响应

1
2
3
4
5
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://frontend.example.com

Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization

接下来会发生什么

  • 浏览器验证服务器的响应。
  • 如果允许请求的方法和标头,则浏览器将继续执行实际请求。
  • 如果不允许,浏览器会在请求到达应用程序逻辑之前阻止该请求。

总结

  • OPTIONS 由浏览器用于 CORS 预检检查。
  • 简单的请求不需要预检。
  • 预检请求确保服务器明确允许潜在的不安全操作。
  • 正确的 CORS 配置对于安全可靠的生产系统至关重要。

HTTP 响应状态代码

HTTP 响应状态代码用于以标准化方式传达客户端请求的结果。
它们通知客户端请求是否成功、失败或需要采取进一步操作。

状态代码是 3 位数字,按第一位数字分组。


状态代码类别

  • 1xx → 信息性
  • 2xx → 成功
  • 3xx → 重定向
  • 4xx → 客户端错误
  • 5xx → 服务器错误

常见状态码及其用法

✅ 成功回复 (2xx)

  • 200(好的)
    表示请求成功,服务器返回了请求的数据(常用GET)。

  • 201(已创建)
    表示请求成功,新资源已创建(常与POST一起使用)。

  • 204(无内容)
    表示请求成功,但服务器没有内容可返回(常用于 CORS 预检 OPTIONS 响应或删除操作)。


🔁 重定向响应 (3xx)

  • 301(永久移动)
    表示请求的资源已永久移动到新的 URL,以后的请求应使用新的 URL。

  • 302(找到)
    指示临时重定向,其中资源暂时可在不同的 URL 上使用,但应继续使用原始 URL。

  • 304(未修改)
    表示资源的缓存版本仍然有效,因此服务器不会重新发送响应正文,从而提高性能。


❌ 客户端错误响应 (4xx)

  • 400(错误请求)
    表示由于客户端数据无效或格式错误,服务器无法处理请求。

  • 401(未经授权)
    表示需要身份验证或提供的凭据丢失或无效。

  • 403(禁止)
    表示客户端已通过身份验证,但无权访问所请求的资源。

  • 404(未找到)
    表示请求成功,但请求的资源在服务器上不存在。

  • 405(不允许的方法)
    指示所请求的资源不支持所使用的 HTTP 方法。

  • 409(冲突)
    指示与资源当前状态的冲突(例如,创建具有重复唯一值的资源)。

  • 429(请求太多)
    指示客户端在给定时间范围内发送了太多请求并且已达到速率限制。


⚠️ 服务器错误响应 (5xx)

  • 500(内部服务器错误)
    表示服务器发生意外错误。

  • 501(未实施)
    表示服务器不支持请求的HTTP方法,但将来可能会实现。

  • 502(网关错误)
    指示服务器从上游服务器收到无效响应。

  • 503(服务不可用)
    表示服务器暂时不可用,通常是由于过载或维护。

  • 504(网关超时)
    表示服务器没有收到上游服务器的及时响应。


总结

  • 状态代码帮助客户了解请求发生了什么
  • 正确使用状态代码可以提高 API 清晰度、调试和客户端处理
  • 正确的状态代码对于 生产级 API 至关重要。

HTTP 缓存

http 缓存是一种用于存储响应副本以供重用的技术。
减少带宽,减少服务器负载并提高效率

有3个重要的标头用于缓存
(1)缓存控制
(2)ETag
(3)最后修改时间

电子标签: 资源的哈希值。如果 E-Tag 与服务器版本匹配,则返回 304 Not Modified 以节省带宽。
**Cache-Control:**定义资源可以在本地存储多长时间(max-age)。

内容协商和压缩

内容协商: 客户端和服务器就格式(JSON 与 XML)和语言达成一致。
压缩: 使用 gzipdeflate 来减小文件大小(例如,将 26MB JSON 缩小到 3.8MB)。