Files

第5-3课:HTTP响应与状态码

一、本课目标

完成本课后,你能够:

  1. 解释HTTP响应状态行、响应头和响应体;
  2. 理解2xx、3xx、4xx和5xx状态码分类;
  3. 为常见业务结果选择合适状态码;
  4. 区分401、403和404;
  5. 使用Python的HTTPStatus避免魔法数字。

二、前置知识

  • 已理解HTTP请求;
  • Python字典、函数和异常;
  • 知道后端业务可能成功,也可能因输入或系统问题失败。

三、HTTP响应结构

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{"id": 1, "title": "Python入门"}
  • 状态行:HTTP版本、状态码和原因短语;
  • 响应头:描述响应内容、缓存和认证等信息;
  • 响应体:页面、JSON、文件或错误详情。

逐行阅读:

  1. HTTP/1.1 200 OK说明HTTP版本和处理结果;
  2. Content-Type说明响应体是UTF-8编码的JSON;
  3. 空行表示响应头结束;
  4. 最后一行JSON是响应体;
  5. 客户端先根据状态码判断结果类别,再按照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。不要把异常详情和堆栈直接返回给外部客户端。

六、选择状态码的思考顺序

遇到业务结果时,可以依次提问:

  1. 请求是否完成了预期操作?完成则从2xx中选择;
  2. 是否需要把客户端引导到其他地址?是则考虑3xx;
  3. 客户端修改请求、身份或操作时机后能否解决?能则通常是4xx;
  4. 是否因为服务器出现未预期故障而无法完成?是则通常是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对象转换成网络报文,但选择状态码仍是后端开发者的责任。

执行过程:

  1. BOOKS保存两条内存图书数据;
  2. 第一次调用find_book(1),字典中存在编号1;
  3. 函数返回HTTPStatus.OK和图书数据;
  4. 第二次调用find_book(99),没有找到图书;
  5. 函数返回HTTPStatus.NOT_FOUND和错误消息;
  6. 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;
  • 示例可独立运行。