HTTP状态码总体分类

HTTP状态码是一个3位数字,由RFC 7231等标准定义。状态码的第一位数字定义了响应的类别,共有5大类:

范围 类别 含义 一句话理解
1xx 信息性状态码 Informational 请求已收到,继续处理
2xx 成功状态码 Success 请求成功处理
3xx 重定向状态码 Redirection 需要进一步操作以完成请求
4xx 客户端错误状态码 Client Error 请求有问题,客户端需要修正
5xx 服务器错误状态码 Server Error 服务器处理请求时出错

状态码的组成

HTTP状态码由三部分组成:

  • 第一位数字:定义响应类别(1-5)
  • 后两位数字:具体状态码(00-99)
  • 状态文本:可读的状态描述(如”OK”、”Not Found”)

例如:200 OK404 Not Found500 Internal Server Error

2xx:成功状态码

2xx系列状态码表示请求已成功被服务器接收、理解并处理。这是Web开发中最常见的状态码类别。

200 OK - 请求成功

含义:请求成功,服务器已成功处理请求并返回响应数据。

使用场景

  • GET请求获取资源成功
  • POST/PUT请求更新资源成功
  • 返回正常的业务数据

示例

1
2
3
4
5
6
7
8
HTTP/1.1 200 OK
Content-Type: application/json

{
"id": 123,
"name": "示例用户",
"email": "user@example.com"
}

注意事项

  • 这是最常用的成功状态码
  • 应该包含请求的资源或操作结果
  • 对于幂等操作(如GET),200表示资源存在且可访问

201 Created - 资源已创建

含义:请求成功,并且服务器创建了新的资源。

使用场景

  • POST请求创建新资源
  • 注册新用户
  • 创建新订单、文章等

示例

1
2
3
4
5
6
7
8
9
HTTP/1.1 201 Created
Location: /api/users/123
Content-Type: application/json

{
"id": 123,
"name": "新用户",
"created_at": "2026-01-12T10:00:00Z"
}

最佳实践

  • 应该包含Location头,指向新创建资源的URI
  • 响应体应包含创建的资源信息
  • 适用于创建操作,区别于200(更新操作)

204 No Content - 无内容

含义:服务器成功处理了请求,但没有返回任何内容。

使用场景

  • DELETE请求成功删除资源
  • PUT请求更新资源,无需返回数据
  • 某些POST请求(如批量操作)只需确认成功

示例

1
HTTP/1.1 204 No Content

注意事项

  • 响应体必须为空
  • 常用于RESTful API的删除操作
  • 客户端收到204后,不应更新其缓存视图(除非请求是DELETE)

其他2xx状态码

202 Accepted:请求已接受,但尚未处理完成(异步操作)

206 Partial Content:部分内容,用于范围请求(Range Request),常用于大文件下载

3xx:重定向状态码

3xx系列状态码表示需要客户端采取进一步的操作才能完成请求。重定向在Web开发中非常常见,特别是在网站迁移、URL规范化、缓存优化等场景。

301 Moved Permanently - 永久重定向

含义:请求的资源已永久移动到新位置,客户端应该使用新的URI访问。

使用场景

  • 网站域名更换(如从http迁移到https)
  • URL结构重构
  • 资源永久迁移到新地址

示例

1
2
HTTP/1.1 301 Moved Permanently
Location: https://www.example.com/new-path

重要特性

  • 浏览器会缓存:客户端会记住这个重定向,以后直接访问新地址
  • SEO影响:搜索引擎会更新索引,将权重转移到新URL
  • HTTP方法可能改变:某些客户端会将POST改为GET(虽然规范不建议)

最佳实践

  • 只在资源确实永久移动时使用
  • 确保新URL可访问且正确
  • 考虑保留旧URL一段时间,返回301重定向

302 Found - 临时重定向

含义:请求的资源临时从不同的URI响应,客户端应继续使用原URI进行后续请求。

使用场景

  • 临时维护页面
  • 登录后跳转
  • A/B测试
  • 临时URL变更

示例

1
2
HTTP/1.1 302 Found
Location: /login?redirect=/dashboard

重要特性

  • 浏览器不缓存:每次都会请求原地址,服务器决定重定向
  • SEO友好:搜索引擎不会更新索引,原URL权重保留
  • HTTP方法保持:重定向后的请求方法通常不变

与301的区别

  • 301:永久移动,浏览器缓存,SEO权重转移
  • 302:临时移动,浏览器不缓存,SEO权重保留

304 Not Modified - 未修改

含义:资源自上次请求后未被修改,客户端可以使用缓存的版本。

使用场景

  • 浏览器缓存验证
  • CDN缓存优化
  • 减少带宽消耗
  • 提升页面加载速度

示例

1
2
3
HTTP/1.1 304 Not Modified
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT

工作原理

  1. 客户端首次请求资源,服务器返回200和缓存头(ETag或Last-Modified)
  2. 客户端再次请求时,带上If-None-Match(ETag)或If-Modified-Since(Last-Modified)
  3. 服务器比较后,如果未修改,返回304;如果已修改,返回200和新内容

性能优化关键

  • 减少网络传输,节省带宽
  • 加快页面加载速度
  • 降低服务器负载

实现示例

1
2
3
4
5
# 伪代码示例
if request.headers.get('If-None-Match') == resource.etag:
return Response(status=304)
else:
return Response(data=resource.data, headers={'ETag': resource.etag})

其他3xx状态码

303 See Other:重定向到另一个URI,且客户端应使用GET方法访问(POST后重定向)

307 Temporary Redirect:临时重定向,但要求客户端保持HTTP方法不变(302的严格版本)

308 Permanent Redirect:永久重定向,且要求客户端保持HTTP方法不变(301的严格版本)

4xx:客户端错误状态码

4xx系列状态码表示客户端发送的请求有错误,服务器无法处理。这类错误通常需要客户端修改请求后才能成功。

400 Bad Request - 请求错误

含义:服务器无法理解客户端的请求,通常是因为请求格式错误。

常见原因

  • 请求参数缺失或格式错误
  • JSON格式不正确,解析失败
  • 参数类型错误(如期望数字却传了字符串)
  • 请求体格式不符合要求
  • URL编码错误

示例

1
2
3
4
5
6
7
8
9
10
11
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
"error": "Invalid request",
"message": "Missing required parameter: 'email'",
"details": {
"field": "email",
"reason": "required"
}
}

最佳实践

  • 返回详细的错误信息,帮助客户端定位问题
  • 列出所有错误字段,而不是只返回第一个错误
  • 使用统一的错误响应格式

401 Unauthorized - 未授权

含义:请求需要身份认证,客户端未提供有效的认证信息。

使用场景

  • 用户未登录
  • Token缺失或格式错误
  • Token已过期
  • 认证信息无效

示例

1
2
3
4
5
6
7
8
9
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="api"
Content-Type: application/json

{
"error": "Unauthorized",
"message": "Authentication required",
"code": "AUTH_REQUIRED"
}

重要特性

  • 应该包含WWW-Authenticate响应头,说明认证方式
  • 客户端收到401后,通常需要重新登录或刷新token
  • 与403的区别:401是”未认证”,403是”已认证但无权限”

常见实现

1
2
3
4
5
6
7
# 伪代码
if not request.headers.get('Authorization'):
return Response(
status=401,
headers={'WWW-Authenticate': 'Bearer'},
data={'error': 'Authentication required'}
)

403 Forbidden - 禁止访问

含义:服务器理解请求,但拒绝执行。客户端已认证,但没有权限访问该资源。

使用场景

  • 用户已登录,但权限不足
  • 访问被管理员禁止的资源
  • IP地址被拉黑
  • 资源访问受限(如付费内容)

示例

1
2
3
4
5
6
7
8
HTTP/1.1 403 Forbidden
Content-Type: application/json

{
"error": "Forbidden",
"message": "You do not have permission to access this resource",
"required_role": "admin"
}

与401的区别

  • 401 Unauthorized:未认证,需要登录
  • 403 Forbidden:已认证,但无权限

最佳实践

  • 明确说明权限要求
  • 不要泄露敏感信息(如”用户存在但密码错误”应返回401,而非403)

404 Not Found - 资源不存在

含义:服务器无法找到请求的资源。

使用场景

  • URL路径错误
  • 资源已被删除
  • API路由未配置
  • 文件不存在

示例

1
2
3
4
5
6
7
8
HTTP/1.1 404 Not Found
Content-Type: application/json

{
"error": "Not Found",
"message": "The requested resource does not exist",
"path": "/api/users/999"
}

注意事项

  • 不要返回404来隐藏资源存在性(安全考虑,某些场景应返回403)
  • 提供友好的错误页面或错误信息
  • 考虑返回相关资源建议(如”您要找的是不是…”)

405 Method Not Allowed - 方法不允许

含义:请求的HTTP方法不被允许用于该资源。

使用场景

  • 对只读资源使用POST/PUT/DELETE
  • API不支持某些HTTP方法
  • 路由配置错误

示例

1
2
3
4
5
6
7
8
9
HTTP/1.1 405 Method Not Allowed
Allow: GET, HEAD
Content-Type: application/json

{
"error": "Method Not Allowed",
"message": "POST method is not allowed for this resource",
"allowed_methods": ["GET", "HEAD"]
}

最佳实践

  • 必须包含Allow响应头,列出允许的方法
  • 帮助客户端了解正确的请求方式

409 Conflict - 资源冲突

含义:请求与资源的当前状态冲突,无法完成。

使用场景

  • 创建资源时,资源已存在(如用户名重复)
  • 更新资源时,版本冲突(乐观锁)
  • 删除资源时,资源正在被使用
  • 并发修改冲突

示例

1
2
3
4
5
6
7
8
9
HTTP/1.1 409 Conflict
Content-Type: application/json

{
"error": "Conflict",
"message": "Username already exists",
"conflict_field": "username",
"conflict_value": "john_doe"
}

乐观锁示例

1
2
3
4
5
6
7
8
9
10
11
# 客户端请求更新资源
PUT /api/articles/123
If-Match: "abc123"

# 服务器检测到版本不匹配
HTTP/1.1 409 Conflict
{
"error": "Version conflict",
"message": "Resource has been modified by another request",
"current_version": "xyz789"
}

最佳实践

  • 提供冲突的详细信息
  • 对于版本冲突,返回当前版本信息,方便客户端重试

429 Too Many Requests - 请求过多

含义:客户端在给定时间内发送了太多请求,需要限流。

使用场景

  • API限流保护
  • 防止恶意刷接口
  • 防止爬虫过度抓取
  • 保护服务器资源

示例

1
2
3
4
5
6
7
8
9
10
11
12
HTTP/1.1 429 Too Many Requests
Retry-After: 60
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1642003200
Content-Type: application/json

{
"error": "Too Many Requests",
"message": "Rate limit exceeded",
"retry_after": 60
}

重要响应头

  • Retry-After:告诉客户端多久后可以重试(秒数或HTTP日期)
  • X-RateLimit-*:自定义限流信息头(非标准但广泛使用)

限流策略

  • 固定窗口:每分钟N次请求
  • 滑动窗口:最近N秒内M次请求
  • 令牌桶:动态分配请求配额
  • 漏桶:平滑处理请求速率

实现示例

1
2
3
4
5
6
7
8
9
10
11
# 伪代码
rate_limit = check_rate_limit(user_id)
if rate_limit.exceeded:
return Response(
status=429,
headers={
'Retry-After': str(rate_limit.retry_after),
'X-RateLimit-Limit': str(rate_limit.limit),
'X-RateLimit-Remaining': str(rate_limit.remaining)
}
)

其他常见4xx状态码

408 Request Timeout:请求超时,客户端发送请求时间过长

410 Gone:资源已永久删除,且不会有新的地址(比404更明确)

422 Unprocessable Entity:请求格式正确,但语义错误(常用于表单验证失败)

451 Unavailable For Legal Reasons:因法律原因不可访问(如被政府要求下架的内容)

5xx:服务器错误状态码

5xx系列状态码表示服务器处理请求时发生错误。这类错误通常是服务器端的问题,客户端无法通过修改请求来解决。

500 Internal Server Error - 服务器内部错误

含义:服务器遇到了意外情况,无法完成请求。

常见原因

  • 代码bug(空指针、数组越界等)
  • 未捕获的异常
  • 数据库连接失败
  • 配置文件错误
  • 内存溢出
  • 第三方服务调用失败

示例

1
2
3
4
5
6
7
8
HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{
"error": "Internal Server Error",
"message": "An unexpected error occurred",
"request_id": "req_123456789"
}

最佳实践

  • 生产环境:不要返回详细的错误堆栈(安全考虑)
  • 开发环境:可以返回详细错误信息便于调试
  • 记录完整的错误日志(包括堆栈、请求参数等)
  • 使用请求ID方便追踪问题
  • 设置错误监控和告警

错误处理示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 伪代码
try:
result = process_request(request)
return Response(data=result)
except Exception as e:
# 记录详细错误
logger.error(f"Internal error: {e}", exc_info=True, extra={
'request_id': request.id,
'user_id': request.user.id
})
# 返回通用错误(生产环境)
return Response(
status=500,
data={
'error': 'Internal Server Error',
'request_id': request.id
}
)

502 Bad Gateway - 网关错误

含义:作为网关或代理的服务器,从上游服务器收到无效响应。

使用场景

  • 反向代理(如Nginx)无法从上游服务器获取有效响应
  • 微服务架构中,API网关无法连接到后端服务
  • 上游服务崩溃或返回无效响应
  • 负载均衡器无法连接到后端服务器

示例

1
2
3
4
5
6
7
HTTP/1.1 502 Bad Gateway
Content-Type: application/json

{
"error": "Bad Gateway",
"message": "Upstream server returned invalid response"
}

常见原因

  • 上游服务宕机
  • 上游服务响应格式错误
  • 网络连接问题
  • 上游服务超时

架构示意

1
2
3
客户端 → API网关 → 上游服务(异常)

返回502

解决方案

  • 实现服务健康检查
  • 配置服务降级策略
  • 使用熔断器模式
  • 增加重试机制

503 Service Unavailable - 服务不可用

含义:服务器暂时无法处理请求,通常是由于维护或过载。

使用场景

  • 服务器正在维护
  • 服务器过载,无法处理更多请求
  • 数据库连接池耗尽
  • 依赖的外部服务不可用
  • 计划内的停机维护

示例

1
2
3
4
5
6
7
8
9
10
HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Content-Type: application/json

{
"error": "Service Unavailable",
"message": "The service is temporarily unavailable",
"retry_after": 3600,
"maintenance_mode": true
}

重要响应头

  • Retry-After:告诉客户端多久后可以重试

与500的区别

  • 500:服务器错误,通常是意外情况
  • 503:服务不可用,通常是已知的临时情况(维护、过载)

最佳实践

  • 提供维护页面或友好的错误信息
  • 设置合理的Retry-After时间
  • 实现优雅降级
  • 使用负载均衡和自动扩缩容

504 Gateway Timeout - 网关超时

含义:作为网关或代理的服务器,未能及时从上游服务器收到响应。

使用场景

  • 上游服务响应时间过长
  • 网络延迟过高
  • 上游服务处理超时
  • 数据库查询超时

示例

1
2
3
4
5
6
7
8
HTTP/1.1 504 Gateway Timeout
Content-Type: application/json

{
"error": "Gateway Timeout",
"message": "Upstream server did not respond in time",
"timeout": 30
}

与502的区别

  • 502:上游服务器返回了无效响应
  • 504:上游服务器没有在超时时间内响应

解决方案

  • 增加超时时间配置
  • 优化上游服务性能
  • 实现异步处理
  • 使用消息队列解耦
  • 设置合理的超时时间

超时配置示例

1
2
3
4
# Nginx配置示例
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

其他5xx状态码

501 Not Implemented:服务器不支持请求的功能(如不支持的HTTP方法)

505 HTTP Version Not Supported:服务器不支持请求中使用的HTTP协议版本


状态码选择的最佳实践

1. 遵循RESTful规范

  • GET:成功返回200,不存在返回404
  • POST:创建成功返回201,其他成功返回200
  • PUT/PATCH:成功返回200或204
  • DELETE:成功返回200或204,不存在返回404

2. 错误处理原则

  • 客户端能修复的错误:返回4xx,提供详细错误信息
  • 服务器端错误:返回5xx,不要泄露内部细节
  • 认证问题:401(未认证)vs 403(已认证但无权限)

3. 状态码一致性

  • 在整个API中保持状态码使用的一致性
  • 建立团队的状态码使用规范
  • 在API文档中明确说明各状态码的使用场景

4. 错误响应格式

建议使用统一的错误响应格式:

1
2
3
4
5
6
7
8
9
10
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {
"field": "additional information"
},
"request_id": "req_123456789"
}
}

5. 监控和日志

  • 记录所有非2xx状态码的请求
  • 设置5xx错误的告警
  • 分析4xx错误模式,优化API设计
  • 监控状态码分布,识别异常