状态码
本文最后更新于72 天前,其中的信息可能已经过时,如有错误请发送邮件到583126841@qq.com

什么是状态码

HTTP 状态码是服务器返回给客户端的三位数字代码,用于表示请求的处理结果。状态码分为 5 大类,每类都有特定的含义。

状态码分类

1xx - 信息性状态码(Informational)
2xx - 成功状态码(Success)
3xx - 重定向状态码(Redirection)
4xx - 客户端错误状态码(Client Error)
5xx - 服务器错误状态码(Server Error)

1xx 信息性状态码

这类状态码表示请求已被接收,继续处理。

100 Continue

含义:服务器已收到请求头,客户端应继续发送请求主体。

使用场景

  • 客户端发送大文件前,先发送请求头
  • 服务器检查请求头后,决定是否接收主体

示例

# 客户端请求
POST /upload HTTP/1.1
Host: example.com
Content-Length: 1048576
Expect: 100-continue

# 服务器响应
HTTP/1.1 100 Continue

# 客户端继续发送主体
[文件数据...]

101 Switching Protocols

含义:服务器同意切换协议。

使用场景

  • WebSocket 握手
  • HTTP/2 升级

示例

# 客户端请求
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade

# 服务器响应
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade

2xx 成功状态码

这类状态码表示请求已成功被服务器接收、理解并处理。

200 OK

含义:请求成功。

使用场景

  • GET 请求成功获取资源
  • POST 请求成功处理
  • PUT/PATCH 请求成功更新

示例

HTTP/1.1 200 OK
Content-Type: application/json

{"id":1,"name":"Zhang San"}

201 Created

含义:请求成功并创建了新资源。

使用场景

  • POST 请求创建新资源
  • PUT 请求创建新资源

示例

HTTP/1.1 201 Created
Location: /api/users/123
Content-Type: application/json

{"id":123,"name":"Zhang San","email":"zhangsan@example.com"}

202 Accepted

含义:请求已接受,但尚未处理完成。
使用场景

  • 异步处理任务
  • 批量操作

示例

HTTP/1.1 202 Accepted
Content-Type: application/json

{"message":"Request accepted","task_id":"abc123"}

204 No Content

含义:请求成功,但没有返回内容。

使用场景

  • DELETE 请求成功
  • PUT 请求成功但不需要返回数据
  • 表单提交成功

示例

HTTP/1.1 204 No Content

206 Partial Content

含义:服务器成功处理了部分 GET 请求。

使用场景

  • 断点续传
  • 视频流播放
  • 大文件下载

示例

HTTP/1.1 206 Partial Content
Content-Range: bytes 0-1023/2048
Content-Length: 1024

[部分内容...]

3xx 重定向状态码

这类状态码表示需要客户端采取进一步的操作才能完成请求。

301 Moved Permanently

含义:资源已永久移动到新位置。

特点

  • 浏览器会缓存新地址
  • 搜索引擎会更新索引

示例

HTTP/1.1 301 Moved Permanently
Location: <https://www.example.com/new-page>

使用场景

  • 网站域名更换
  • URL 结构调整
  • HTTP 升级到 HTTPS

302 Found

含义:资源临时移动到新位置。

特点

  • 浏览器不会缓存
  • 搜索引擎不会更新索引

示例

HTTP/1.1 302 Found
Location: /temporary-page

使用场景

  • 临时维护页面
  • A/B 测试
  • 临时跳转

303 See Other

含义:使用 GET 方法访问另一个 URL。

使用场景

  • POST 请求后重定向到结果页面
  • 防止表单重复提交

示例

HTTP/1.1 303 See Other
Location: /success-page

304 Not Modified

含义:资源未修改,可以使用缓存。

使用场景

  • 条件 GET 请求
  • 浏览器缓存验证

示例

# 客户端请求
GET /image.jpg HTTP/1.1
If-Modified-Since: Mon, 27 Jul 2024 12:00:00 GMT

# 服务器响应
HTTP/1.1 304 Not Modified

307 Temporary Redirect

含义:临时重定向,保持原请求方法。

与 302 的区别

  • 307 保证不改变请求方法
  • 302 可能将 POST 改为 GET

示例

HTTP/1.1 307 Temporary Redirect
Location: /new-location

308 Permanent Redirect

含义:永久重定向,保持原请求方法。

与 301 的区别

  • 308 保证不改变请求方法
  • 301 可能将 POST 改为 GET

示例

HTTP/1.1 308 Permanent Redirect
Location: /new-permanent-location

4xx 客户端错误状态码

这类状态码表示客户端的请求有错误。

400 Bad Request

含义:请求语法错误,服务器无法理解。

常见原因

  • JSON 格式错误
  • 缺少必需参数
  • 参数类型错误

示例
GET 请求的 URL 中包含非法字符(如未转义的空格、中文)
curl http://example.com/api?name=test user

HTTP/1.1 400 Bad Request
Content-Type: application/json

{"error":"Invalid JSON format"}

401 Unauthorized

含义:需要身份认证。

特点

  • 需要提供认证信息
  • 通常返回 WWW-Authenticate 头部

示例

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Basic realm="Access to API"
Content-Type: application/json

{"error":"Authentication required"}

403 Forbidden

含义:服务器理解请求,但拒绝执行。

与 401 的区别

  • 401:未认证
  • 403:已认证但无权限

示例

HTTP/1.1 403 Forbidden
Content-Type: application/json

{"error":"You don't have permission to access this resource"}

404 Not Found

含义:请求的资源不存在。

使用场景

  • URL 路径错误
  • 资源已被删除
  • API 端点不存在

示例

HTTP/1.1 404 Not Found
Content-Type: application/json

{"error":"Resource not found"}

405 Method Not Allowed

含义:请求方法不被允许。

特点

  • 返回 Allow 头部,列出允许的方法

示例

HTTP/1.1 405 Method Not Allowed
Allow: GET, POST
Content-Type: application/json

{"error":"DELETE method is not allowed"}

408 Request Timeout

含义:服务器等待请求超时。

使用场景

  • 客户端发送请求过慢
  • 网络连接不稳定

示例

HTTP/1.1 408 Request Timeout
Content-Type: application/json

{"error":"Request timeout"}

409 Conflict

含义:请求与服务器当前状态冲突。

使用场景

  • 资源版本冲突
  • 重复创建资源
  • 并发修改冲突

示例

HTTP/1.1 409 Conflict
Content-Type: application/json

{"error":"User with this email already exists"}

413 Payload Too Large

含义:请求主体过大。

使用场景

  • 上传文件过大
  • POST 数据过多

示例

HTTP/1.1 413 Payload Too Large
Content-Type: application/json

{"error":"File size exceeds 10MB limit"}

415 Unsupported Media Type

含义:不支持的媒体类型。

使用场景

  • Content-Type 不正确
  • 服务器不支持该格式(比如你请求的content type是json,但是服务器支持的是text/html)

示例

HTTP/1.1 415 Unsupported Media Type
Content-Type: application/json

{"error":"Content-Type must be application/json"}

429 Too Many Requests

含义:请求过多,触发限流。

使用场景

  • API 限流
  • 防止滥用

示例

HTTP/1.1 429 Too Many Requests
Retry-After: 60
Content-Type: application/json

{"error":"Rate limit exceeded. Try again in 60 seconds"}

5xx 服务器错误状态码

这类状态码表示服务器在处理请求时发生错误。

500 Internal Server Error

含义:服务器内部错误。

常见原因

  • 代码异常
  • 数据库错误
  • 配置错误

示例

HTTP/1.1 500 Internal Server Error
Content-Type: application/json

{"error":"Internal server error"}

501 Not Implemented

含义:服务器不支持该功能。

使用场景

  • 请求的功能未实现
  • 不支持的 HTTP 方法

示例

HTTP/1.1 501 Not Implemented
Content-Type: application/json

{"error":"This feature is not implemented"}

502 Bad Gateway

含义:网关或代理服务器收到无效响应。

使用场景

  • 上游服务器故障
  • 代理配置错误

示例

HTTP/1.1 502 Bad Gateway
Content-Type: application/json

{"error":"Bad gateway"}

503 Service Unavailable

含义:服务暂时不可用。

常见原因

  • 服务器维护
  • 服务器过载
  • 临时故障

示例

HTTP/1.1 503 Service Unavailable
Retry-After: 3600
Content-Type: application/json

{"error":"Service temporarily unavailable"}

504 Gateway Timeout

含义:网关或代理服务器超时。

使用场景

  • 上游服务器响应慢
  • 网络延迟

示例

HTTP/1.1 504 Gateway Timeout
Content-Type: application/json

{"error":"Gateway timeout"}

常用状态码速查表

状态码含义常见场景
200OK请求成功
201Created资源创建成功
204No Content删除成功
301Moved Permanently永久重定向
302Found临时重定向
304Not Modified使用缓存
400Bad Request请求格式错误
401Unauthorized需要认证
403Forbidden无权限
404Not Found资源不存在
405Method Not Allowed方法不允许
429Too Many Requests请求过多
500Internal Server Error服务器错误
502Bad Gateway网关错误
503Service Unavailable服务不可用

状态码选择指南

成功响应

  • 200:通用成功响应
  • 201:创建资源成功
  • 204:成功但无内容返回

重定向

  • 301:永久重定向(SEO 友好)
  • 302:临时重定向
  • 304:资源未修改(缓存)

客户端错误

  • 400:请求格式错误
  • 401:未认证
  • 403:已认证但无权限
  • 404:资源不存在
  • 409:资源冲突

服务器错误

  • 500:通用服务器错误
  • 503:服务暂时不可用

状态码的安全意义

理解状态码不仅有助于调试和 API 设计,更重要的是它们与 Web 安全密切相关。

1. 认证和授权相关状态码的安全实践

401 Unauthorized 的正确使用

安全问题:不当的 401 响应可能泄露敏感信息。

错误示例

HTTP/1.1 401 Unauthorized{  "error": "用户名 'admin' 存在,但密码错误"}

问题:攻击者可以通过这个响应枚举有效的用户名。

正确示例

HTTP/1.1 401 Unauthorized{  "error": "用户名或密码错误"}

最佳实践

  • 不要在错误消息中区分”用户名不存在”和”密码错误”
  • 登录失败时返回统一的错误消息
  • 实现登录尝试限制,防止暴力破解
  • 使用相同的响应时间,避免时序攻击

完整的安全登录响应

HTTP/1.1 401 Unauthorized
Content-Type: application/json
WWW-Authenticate: Bearer realm="api"
X-RateLimit-Remaining: 2

{
  "error": "认证失败",
  "message": "用户名或密码错误",
  "retry_after": 3
}

403 Forbidden 的安全考虑

403 vs 404 的选择

场景:用户尝试访问其他用户的私有资源

选项 1:返回 403 Forbidden
GET /api/users/123/private-data
HTTP/1.1 403 Forbidden
问题:确认了资源存在,可能泄露信息

选项 2:返回 404 Not Found
GET /api/users/123/private-data
HTTP/1.1 404 Not Found
优点:隐藏资源的存在性,更安全

安全原则

  1. 对于敏感资源:返回 404 而不是 403 示例:用户尝试访问不属于自己的订单 返回 404,让攻击者无法确认订单是否存在
  2. 对于公开资源:可以返回 403 示例:未登录用户访问需要登录的页面 返回 403,明确告知需要认证
  3. 记录可疑的 403 请求if (response.status === 403) { logger.warn('Unauthorized access attempt', { user: req.user.id, resource: req.path, ip: req.ip, timestamp: new Date() });}

2. 重定向状态码的安全风险

开放重定向漏洞

什么是开放重定向?

攻击者利用重定向功能将用户引导到恶意网站。

漏洞示例

// 危险代码app.get('/redirect', (req, res) => {
    const url = req.query.url;    res.redirect(302, url);  // 直接使用用户输入});// 攻击 URLhttps://bank.com/redirect?url=https://evil.com/fake-login

攻击流程

1. 攻击者发送钓鱼邮件:
   "您的账户有异常,请点击链接验证:
   <https://bank.com/redirect?url=https://evil.com/fake-login>"

2. 用户看到 bank.com 域名,信任并点击

3. bank.com 将用户重定向到 evil.com

4. evil.com 显示伪造的登录页面

5. 用户输入凭据,被攻击者窃取

安全防护

最佳实践

  1. 使用白名单:只允许重定向到可信域名
  2. 验证 URL 格式:确保是有效的 URL
  3. 使用相对路径:优先使用站内相对路径
  4. 记录重定向:记录所有重定向请求以便审计

301 vs 302 的安全影响

301 Moved Permanently(永久重定向)

影响:
- 浏览器会缓存重定向
- 搜索引擎会更新索引
- 可能导致旧 URL 永久失效

安全考虑:
- 确保新 URL 长期有效
- 避免将敏感 URL 永久重定向到不安全的位置

302 Found(临时重定向)

影响:
- 浏览器不会缓存
- 搜索引擎保留原 URL
- 适合临时性的重定向

安全考虑:
- 适合登录后的重定向
- 适合临时维护页面

3. 错误状态码的信息泄露风险

500 Internal Server Error 的安全处理

危险示例

泄露的信息

  • 数据库类型(MySQL)
  • 数据库用户名(root)
  • 数据库密码(password)
  • 服务器内部路径
  • 技术栈信息

正确示例

安全实践

404 Not Found 的安全应用

用途 1:隐藏资源存在性

用途 2:防止路径遍历

4. 状态码与速率限制

429 Too Many Requests 的安全应用

响应示例

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 900
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1640000000

{
  "error": "请求过于频繁",
  "message": "您已超过登录尝试次数限制",
  "retry_after": 900
}

5. 缓存相关状态码的安全考虑

304 Not Modified 的安全使用

问题场景:敏感数据被缓存

# 第一次请求
GET /api/user/profile
HTTP/1.1 200 OK
ETag: "abc123"
Cache-Control: private, max-age=3600

{"name":"Zhang San","salary":50000}

# 第二次请求
GET /api/user/profile
If-None-Match: "abc123"

HTTP/1.1 304 Not Modified
# 浏览器使用缓存的数据

安全风险

  • 敏感数据被缓存在浏览器中
  • 共享设备上可能被其他用户访问
  • 缓存可能在用户登出后仍然存在

安全实践

状态码安全检查清单

在设计和实现 API 时,请检查以下项目:

  • [ ] 401 响应不泄露用户名是否存在
  • [ ] 敏感资源返回 404 而不是 403
  • [ ] 实现了开放重定向防护
  • [ ] 500 错误不返回敏感的技术细节
  • [ ] 实现了速率限制(429)
  • [ ] 敏感数据不使用 304 缓存
  • [ ] 错误响应包含唯一的错误 ID
  • [ ] 记录所有认证失败(401)和授权失败(403)
  • [ ] 为不同的错误场景返回合适的状态码
  • [ ] 生产环境隐藏详细的错误堆栈

思考题

  1. 301 和 302 的主要区别是什么?
  2. 401 和 403 有什么不同?什么时候应该返回 404 而不是 403?
  3. 什么时候应该返回 204 状态码?
  4. 为什么需要 304 状态码?它有什么安全风险?
  5. 如果登录失败时返回”用户名不存在”或”密码错误”,会有什么安全问题?
  6. 为什么生产环境的 500 错误不应该返回详细的错误信息?

小结

  • HTTP 状态码分为 5 大类(1xx-5xx),每类有特定含义
  • 2xx 成功:请求被正确处理
  • 3xx 重定向:需要客户端采取进一步操作,注意开放重定向风险
  • 4xx 客户端错误:请求有误,注意信息泄露风险
  • 5xx 服务器错误:服务器处理失败,不要返回敏感信息
  • 正确使用状态码是 API 设计和安全的基础
  • 401/403 响应要避免泄露敏感信息
  • 敏感资源考虑返回 404 而不是 403
  • 实现开放重定向防护
  • 500 错误不返回技术细节
  • 使用 429 实现速率限制
  • 敏感数据避免使用缓存相关状态码
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇