第5-3课:HTTP响应与状态码
一、本课目标
完成本课后,你能够:
- 解释HTTP响应状态行、响应头和响应体;
- 理解2xx、3xx、4xx和5xx状态码分类;
- 为常见业务结果选择合适状态码;
- 区分401、403和404;
- 使用Python的
HTTPStatus避免魔法数字。
二、前置知识
- 已理解HTTP请求;
- Python字典、函数和异常;
- 知道后端业务可能成功,也可能因输入或系统问题失败。
三、HTTP响应结构
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{"id": 1, "title": "Python入门"}
- 状态行:HTTP版本、状态码和原因短语;
- 响应头:描述响应内容、缓存和认证等信息;
- 响应体:页面、JSON、文件或错误详情。
逐行阅读:
HTTP/1.1 200 OK说明HTTP版本和处理结果;Content-Type说明响应体是UTF-8编码的JSON;- 空行表示响应头结束;
- 最后一行JSON是响应体;
- 客户端先根据状态码判断结果类别,再按照
Content-Type解析响应体。
状态码是给程序和人共同使用的标准信号,原因短语OK主要帮助阅读。客户端逻辑应依赖状态码,不应依赖英文短语。
四、状态码分类
| 范围 | 含义 | 常见情况 |
|---|---|---|
| 1xx | 信息响应 | 处理中,入门阶段很少手工处理 |
| 2xx | 成功 | 查询、创建、更新或删除成功 |
| 3xx | 重定向 | 资源位置变化或缓存仍有效 |
| 4xx | 客户端请求问题 | 参数、认证、权限或资源错误 |
| 5xx | 服务器处理失败 | 未处理异常或上游服务失败 |
五、常用状态码
| 状态码 | 常见使用场景 |
|---|---|
| 200 OK | 成功并返回内容 |
| 201 Created | 成功创建资源,通常附带Location头 |
| 204 No Content | 成功但没有响应体 |
| 400 Bad Request | 请求格式或通用参数错误 |
| 401 Unauthorized | 尚未完成身份认证,名称虽是Unauthorized,实际常表示未认证 |
| 403 Forbidden | 身份已知,但没有访问权限 |
| 404 Not Found | 资源不存在 |
| 409 Conflict | 当前状态冲突,例如编号重复 |
| 422 Unprocessable Content | 格式可解析,但字段校验或语义不符合要求 |
| 500 Internal Server Error | 服务器出现未预期错误 |
业务失败不一定是500。例如图书不存在是404,重复编号可以是409。不要把异常详情和堆栈直接返回给外部客户端。
六、选择状态码的思考顺序
遇到业务结果时,可以依次提问:
- 请求是否完成了预期操作?完成则从2xx中选择;
- 是否需要把客户端引导到其他地址?是则考虑3xx;
- 客户端修改请求、身份或操作时机后能否解决?能则通常是4xx;
- 是否因为服务器出现未预期故障而无法完成?是则通常是5xx。
进一步判断:
- 成功返回内容:通常200;
- 成功创建新资源:201;
- 成功且没有响应体:204;
- JSON根本无法解析:400;
- JSON可解析但字段不符合约束:常用422;
- 当前资源状态与操作冲突:409;
- 代码出现未处理异常:500。
状态码选择可能受团队规范影响,但同一项目应保持一致并写入接口文档。
七、401、403、404详细对比
假设用户请求删除一本图书:
- 没有登录凭证:401,客户端需要先认证;
- 已登录但不是管理员:403,身份明确但操作被禁止;
- 有权限但图书编号不存在:404;
- 删除成功且不返回正文:204。
有些安全敏感接口会用404隐藏资源是否存在,这是安全策略,需要由项目统一决定,不能随意混用。
八、完整示例
response_status_example.py使用标准库HTTPStatus表示状态码,分别生成图书存在和不存在的响应。
九、运行方法
cd D:\Code\Python\05_web基础\5_3_HTTP响应与状态码
python response_status_example.py
关键输出:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
响应体:{'id': 1, 'title': 'Python入门'}
---
HTTP/1.1 404 Not Found
十、关键代码解析
find_book()根据业务结果选择状态码;print_response()读取枚举的数值和原因短语。实际框架会负责把Python对象转换成网络报文,但选择状态码仍是后端开发者的责任。
执行过程:
BOOKS保存两条内存图书数据;- 第一次调用
find_book(1),字典中存在编号1; - 函数返回
HTTPStatus.OK和图书数据; - 第二次调用
find_book(99),没有找到图书; - 函数返回
HTTPStatus.NOT_FOUND和错误消息; print_response()把两种结果按响应结构输出。
HTTPStatus是Python标准库提供的枚举,HTTPStatus.NOT_FOUND比直接写404更容易读懂。它最终仍能通过.value取得数字404。
十一、常见错误
11.1 HTTP永远返回200
只在响应体里写“失败”会让客户端、监控和网关难以判断真实结果。
11.2 把所有异常都返回500
输入错误、资源不存在和权限不足属于可预期结果,应明确使用4xx。
11.3 给204响应添加响应体
204的含义就是没有响应内容,需要返回内容时选择200等状态码。
11.4 只看响应消息,不看状态码
错误消息可能变化或被翻译,状态码才是客户端判断结果类别的标准信号。
11.5 把程序异常详情返回客户端
堆栈、SQL和服务器路径可能泄露内部信息。外部响应应提供安全的错误说明,详细异常写入受控日志。
十二、课堂练习
打开practice.py,完成状态码选择和创建资源响应练习。
十三、本课小结
状态码是HTTP层的统一结果语言。响应体提供细节,不能代替准确的状态码;准确的状态码也不能代替清晰、安全的错误信息。
十四、验收标准
- 能解释HTTP响应的主要部分;
- 能区分2xx、4xx和5xx;
- 能正确区分401、403和404;
- 能为创建、删除和校验失败选择状态码;
- 能按顺序判断一个结果属于2xx、4xx还是5xx;
- 示例可独立运行。