1. HTTP 请求方法
HTTP(Hypertext Transfer Protocol)是用于客户端与服务器之间通信的应用层协议。
| HTTP 方法 | 对应 CRUD | 作用 | 幂等性 |
|---|---|---|---|
| GET | READ | 获取资源 | 是 |
| POST | CREATE | 创建资源或提交数据进行处理 | 否(默认) |
| PUT | UPDATE | 创建或完整替换目标资源 | 是 |
| PATCH | UPDATE | 部分修改资源 | 不保证 |
| DELETE | DELETE | 删除资源 | 是 |
| HEAD | READ | 只获取响应头,不返回响应体 | 是 |
| OPTIONS | — | 查询服务器支持的通信选项 | 是 |
幂等性(Idempotency)
相同的请求执行一次和执行多次,对服务器产生的预期效果相同,就称为幂等。
例如:
GET /users/1:重复读取,不应改变服务器资源状态。PUT /users/1:重复提交相同内容,资源的最终状态相同。DELETE /users/1:重复删除,资源最终都处于不存在的状态。POST /orders:重复提交可能创建多个订单,因此默认不幂等。
注意:幂等不意味着每次响应完全相同。例如重复删除某个资源,第一次可能返回 204,第二次返回 404。
HTTP 还区分安全方法(Safe Methods)。GET、HEAD、OPTIONS 都属于安全方法,意味着客户端不请求改变服务器资源状态。
2. HTTP 无状态
HTTP 是无状态协议(Stateless Protocol)。
含义是:服务器处理某一次 HTTP 请求时,不依赖 HTTP 协议自动记住之前请求的上下文。
例如:
Client → GET /products
Server → Products
Client → GET /profile
Server → Profile
每次请求都需要提供服务器处理该请求所需的信息。
但无状态不代表服务器不能保存用户信息。
实际应用中:
- Cookie:浏览器保存 Cookie,并在后续请求中发送。
- Session:服务器可以保存会话状态,客户端通过 Session ID 标识会话。
- JWT:客户端可以携带 Token,服务器验证后识别用户。
HTTP 本身是无状态的,但 Web 应用可以通过 Cookie、Session、Token 等机制实现有状态的用户会话。
另外,HTTP Keep-Alive 可以复用 TCP 连接,但连接复用与应用层会话状态是两个不同概念。
3. URL 结构
常见 URL 结构:
scheme://host:port/path?query#fragment
例如:
https://api.example.com:443/api/v1/users?page=2#details
| 组成 | 说明 |
|---|---|
| scheme | 协议,如 HTTP、HTTPS |
| host | 域名或 IP 地址 |
| port | 服务器端口 |
| path | 资源路径 |
| query | 查询参数 |
| fragment | 页面片段标识符 |
补充:
- HTTP 默认端口为 80。
- HTTPS 默认端口为 443。
- Query 参数常用于搜索、过滤、分页、排序。
- Fragment 通常由浏览器在客户端处理,不会作为普通 HTTP 请求目标的一部分发送到服务器。
URI 是资源标识符,URL 是 URI 的一种,用于定位资源。
4. RESTful API 设计规范
REST(Representational State Transfer)是一种架构风格。
RESTful API 通常以资源为中心,通过 HTTP 方法表示操作。
URL 设计
推荐使用名词和复数形式:
/api/v1/users
/api/v1/users/{user_id}
/api/v1/users/{user_id}/orders
/api/v1/users/{user_id}/orders/{order_id}
一般不建议在 URL 中重复使用动词:
GET /getUsers
POST /createUser
DELETE /deleteUser/1
更推荐:
GET /users
POST /users
GET /users/1
PUT /users/1
PATCH /users/1
DELETE /users/1
不过对于无法自然映射为 CRUD 的业务操作,也可以使用动作型端点,例如:
POST /orders/123/cancel
POST /payments/123/refund
此类设计属于常见的工程实践,并非 REST 强制禁止或要求。
URL 设计原则
- 使用名词描述资源,通常采用复数形式。
- 利用 HTTP 方法区分操作。
- 使用 Query 参数实现搜索、过滤、排序和分页。
- 保持 URL 层级简单,避免过深嵌套。
- API 版本可以放在 URL 中,例如
/api/v1/,但这不是唯一版本管理方式。
5. Query Parameters
Query 参数通常用于 GET 请求:
GET /api/v1/pois?city=1&limit=20&offset=40
| 参数 | 用途 |
|---|---|
city=1 | 过滤 |
limit=20 | 每次返回 20 条 |
offset=40 | 跳过前 40 条 |
ordering=-score | 按分数降序 |
search=Tokyo | 搜索关键字 |
对于复杂搜索,也可以使用 POST 携带 JSON 请求体,但应清楚定义该接口的查询语义。
6. HTTP Request / Response
Request 结构
POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer <token>
{
"name": "Alice",
"age": 25
}
主要包含:
- Request Method:请求方法。
- URL:请求资源。
- Headers:请求元数据。
- Body:请求内容(如果存在)。
Response 结构
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/users/123
{
"id": 123,
"name": "Alice",
"age": 25
}
主要包含:
- Status Code:响应状态码。
- Headers:响应元数据。
- Body:响应内容(如果存在)。
7. 常见 HTTP Header
| Header | 作用 |
|---|---|
| Content-Type | 请求体或响应体的数据类型 |
| Accept | 客户端希望接收的数据类型 |
| Authorization | 携带认证凭据 |
| Cookie | 浏览器向服务器发送 Cookie |
| Set-Cookie | 服务器要求浏览器设置 Cookie |
| Cache-Control | 控制缓存策略 |
| Accept-Encoding | 客户端支持的压缩算法 |
| Content-Encoding | 响应内容采用的压缩算法 |
| Origin | 请求来源的源信息,常用于 CORS |
| Access-Control-Allow-Origin | 指定允许跨源访问的来源 |
| ETag | 资源版本标识,用于缓存验证 |
Content-Type 与 Accept
Content-Type: application/json
Accept: application/json
区别:
Content-Type:当前传输内容是什么格式。Accept:客户端希望服务器返回什么格式。
Accept-Encoding 与 Content-Encoding
Accept-Encoding: br, gzip
Content-Encoding: br
浏览器支持 Brotli 和 gzip,服务器选择 Brotli 压缩响应。
8. HTTP 状态码
HTTP 状态码分为五类:
| 范围 | 类别 | 含义 |
|---|---|---|
| 1xx | Informational | 信息性响应 |
| 2xx | Success | 请求成功 |
| 3xx | Redirection | 重定向或缓存验证 |
| 4xx | Client Error | 客户端请求错误 |
| 5xx | Server Error | 服务器错误 |
2xx 成功
| 状态码 | 名称 | 含义 |
|---|---|---|
| 200 | OK | 请求成功,通常返回数据 |
| 201 | Created | 成功创建资源 |
| 202 | Accepted | 请求已被接受,但处理尚未完成 |
| 204 | No Content | 请求成功,没有响应体 |
常见用法:
- GET 成功:200
- POST 创建成功:201
- PUT/PATCH 修改成功:200 或 204
- DELETE 成功:204
- 异步任务已接受:202
202 不保证异步任务最终执行成功。
3xx 重定向
| 状态码 | 名称 | 含义 |
|---|---|---|
| 301 | Moved Permanently | 永久重定向 |
| 302 | Found | 临时重定向 |
| 304 | Not Modified | 资源未修改,可复用缓存 |
| 307 | Temporary Redirect | 临时重定向,保留请求方法 |
| 308 | Permanent Redirect | 永久重定向,保留请求方法 |
注意:304 通常用于条件请求,与普通的页面跳转不同。
4xx 客户端错误
| 状态码 | 名称 | 含义 |
|---|---|---|
| 400 | Bad Request | 请求格式错误或参数不合法 |
| 401 | Unauthorized | 缺少有效认证凭据 |
| 403 | Forbidden | 服务器拒绝执行请求 |
| 404 | Not Found | 资源不存在或未公开 |
| 405 | Method Not Allowed | 不支持该 HTTP 方法 |
| 406 | Not Acceptable | 无法提供符合 Accept 要求的响应 |
| 409 | Conflict | 与当前资源状态冲突 |
| 410 | Gone | 资源已永久不可用 |
| 413 | Content Too Large | 请求内容超过服务器限制 |
| 415 | Unsupported Media Type | 不支持请求体的数据格式 |
| 422 | Unprocessable Content | 请求格式可识别,但内容无法处理 |
| 429 | Too Many Requests | 请求过于频繁,触发限流 |
401 与 403 的区别
- 401:客户端缺少有效认证凭据,通常需要登录或重新认证。
- 403:服务器理解请求,但拒绝执行,即使客户端已通过认证也可能返回 403。
400 与 422 的区别
- 400:通常表示请求格式或参数错误,也可以涵盖请求验证失败。
- 422:请求语法正确、内容类型可识别,但服务器无法处理其中的指令或语义。
不同框架对验证错误的状态码选择可能不同。
例如 Django REST Framework 的 Serializer 验证失败通常返回 400,而 FastAPI 的请求数据验证错误通常返回 422。
5xx 服务器错误
| 状态码 | 名称 | 含义 |
|---|---|---|
| 500 | Internal Server Error | 服务器内部错误 |
| 502 | Bad Gateway | 网关收到无效上游响应 |
| 503 | Service Unavailable | 服务暂时不可用 |
| 504 | Gateway Timeout | 网关等待上游响应超时 |
对于 Nginx + Django 架构:
- 500:Django 内部异常可能导致。
- 502:Nginx 无法获得有效的 Django 上游响应。
- 503:服务器暂时无法提供服务。
- 504:Nginx 等待 Django 上游响应超时。
9. HTTP 缓存
HTTP 缓存可以避免重复下载未变化的资源。
常见响应头:
Cache-Control: public, max-age=31536000, immutable
通常用于带内容哈希的 JS、CSS 静态资源。
常见 Cache-Control 指令:
| 指令 | 含义 |
|---|---|
| public | 允许共享缓存存储 |
| private | 响应只能由私有缓存存储 |
| no-cache | 复用缓存前必须验证 |
| no-store | 不允许缓存存储响应 |
| max-age=3600 | 缓存新鲜期为 3600 秒 |
| immutable | 新鲜期内资源不会改变 |
ETag 缓存验证
浏览器第一次请求:
GET /api/v1/data
服务器返回:
HTTP/1.1 200 OK
ETag: "abc123"
再次请求:
GET /api/v1/data
If-None-Match: "abc123"
如果资源没有变化,服务器可以返回:
HTTP/1.1 304 Not Modified
浏览器继续使用缓存中的内容。
10. CORS 与 CSRF
CORS(Cross-Origin Resource Sharing)
浏览器通过同源策略限制跨源读取响应。CORS 允许服务器声明哪些跨源请求可以被浏览器访问。
例如:
Access-Control-Allow-Origin: https://example.com
跨源请求在某些情况下会先发送 OPTIONS 预检请求(Preflight Request)。
CORS 主要是浏览器安全机制,不是后端 API 的身份认证机制。
CSRF(Cross-Site Request Forgery)
CSRF 是利用浏览器自动携带 Cookie 等认证凭据,诱导用户在已登录网站执行非预期操作的攻击。
常见防御手段:
- CSRF Token。
- Cookie 的 SameSite 属性。
- 检查 Origin / Referer。
- 不使用 GET 实现修改服务器状态的操作。
CORS 与 CSRF 是不同的安全机制,不能互相替代。
11. HTTP/1.1、HTTP/2、HTTP/3
| 特性 | HTTP/1.1 | HTTP/2 | HTTP/3 |
|---|---|---|---|
| 底层传输 | TCP | TCP | QUIC(基于 UDP) |
| 多路复用 | 无 HTTP/2 式多路复用 | 支持 | 支持 |
| Header 压缩 | 无专门的 Header 压缩机制 | HPACK | QPACK |
| 传输层队头阻塞 | 存在 | 存在 | 避免 TCP 式跨流队头阻塞 |
核心区别:
- HTTP/1.1:广泛兼容,常利用多个 TCP 连接提高并发能力。
- HTTP/2:在一条连接上多路复用多个请求,提高传输效率。
- HTTP/3:基于 QUIC,改善丢包情况下的多流传输表现。
HTTP/2 和 HTTP/3 并不会改变 GET、POST 等方法的基本语义。
总结
HTTP 与 RESTful API 的核心知识:
| 模块 | 重点 |
|---|---|
| HTTP Method | GET、POST、PUT、PATCH、DELETE |
| HTTP 特性 | 无状态、安全性、幂等性 |
| URL | Scheme、Host、Port、Path、Query |
| RESTful | 资源导向、HTTP 方法、状态码 |
| Request/Response | Header、Body、Status Code |
| HTTP 状态码 | 2xx、3xx、4xx、5xx |
| 缓存 | Cache-Control、ETag、304 |
| 安全 | HTTPS、Authentication、CORS、CSRF |
| HTTP 版本 | HTTP/1.1、HTTP/2、HTTP/3 |
对于后端 API 开发,最需要掌握的是 HTTP 方法的语义、状态码的正确使用、幂等性、认证授权、缓存策略和跨域安全。
参考文档: