1025 字
3 分钟
PythonWebpython web
HTTP 基础:请求-响应模型、报文结构与状态码

在写任何 Web 框架之前,先理解 HTTP 本身:请求-响应模型、报文结构、方法语义、状态码分类和常见 Header。这是 Python Web 和 Java Web 共同的地基。

框架会变,HTTP 不会。不管你用的是 FastAPI、Flask、Spring Boot 还是 Express,底层都是同一个协议在跑。这一篇把 HTTP 的核心概念收在一起,作为整个 Python Web 系列的地基。

Java Web 对比:Java 生态里,Servlet 规范(HttpServletRequest / HttpServletResponse)就是对 HTTP 报文的对象级封装。FastAPI 的 Request 对象本质上在干同一件事——把原始 HTTP 报文解析成程序可操作的结构。理解 HTTP 本身之后,两边框架的 API 差异就只是语法糖。

1. HTTP 是什么#

HTTP(HyperText Transfer Protocol)是 Web 的通信协议。它的工作模型极其简单:

客户端 服务端
| |
|──── 请求 (Request) ──────────→|
| | (处理)
|←─── 响应 (Response) ──────────|
| |

一次交互就是一个请求-响应对。服务端不会主动给客户端推消息(HTTP/1.1 如此,HTTP/2 有 Server Push 但已被废弃)。

2. 请求报文的结构#

一个 HTTP 请求由四部分组成:

POST /api/items HTTP/1.1 ← 请求行:方法 + 路径 + 协议版本
Host: example.com ← 请求头:键值对元信息
Content-Type: application/json
Authorization: Bearer xxx
{"name": "Foo", "price": 42.0} ← 请求体:数据(GET 请求通常没有)

请求行三个要素:

部分示例含义
方法POST要对资源做什么
路径/api/items操作哪个资源
协议版本HTTP/1.1用哪版协议

Java Web 对比:Spring Boot 的 @PostMapping("/api/items") 本质上就是在声明"当收到 POST /api/items 时调用这个方法"。FastAPI 的 @app.post("/api/items") 同理。

3. HTTP 方法的语义#

方法语义安全幂等典型场景
GET获取资源查询、读取
POST创建资源新增、提交
PUT整体替换全量更新
PATCH部分修改局部更新
DELETE删除资源删除

安全:不改变服务端状态。幂等:执行一次和执行多次效果相同。

这些语义不是你"守规矩"的问题——浏览器、CDN、搜索引擎爬虫都会根据方法做出不同行为。比如 GET 请求可以被 CDN 缓存,POST 不会。

4. 状态码:服务端的"一句话回复"#

状态码不只是一个数字,它是服务端对请求结果的语义表达。

范围类别最常见
1xx信息101 协议切换(WebSocket)
2xx成功200 OK201 Created204 No Content
3xx重定向301 永久、302 临时、304 未修改
4xx客户端错误400 Bad Request401 Unauthorized403 Forbidden404 Not Found422 Unprocessable
5xx服务端错误500 Internal Server Error502 Bad Gateway503 Service Unavailable

设计中最重要的抉择401 vs 403——401 是"你没给我凭证",403 是"我知道你是谁但你没权限"。404 vs 422——404 是"资源不存在",422 是"资源存在但你给的数据不对"。

Java Web 对比:Spring 用 @ResponseStatus(HttpStatus.CREATED) 注解,FastAPI 用 status_code=201 参数。语义完全一样,语法不同。

5. 常见请求头和响应头#

请求头(客户端→服务端):

Header作用
Host目标主机(HTTP/1.1 必须)
Content-Type请求体的格式,如 application/json
Authorization认证凭证
Accept客户端能接收的响应格式
User-Agent客户端标识
Cookie携带会话信息

响应头(服务端→客户端):

Header作用
Content-Type响应体的格式
Content-Length响应体字节数
Set-Cookie让浏览器存 Cookie
Cache-Control缓存策略
Location重定向目标(配合 3xx)
Access-Control-Allow-OriginCORS 白名单

6. 内容协商:Content-TypeAccept#

一次请求里,Content-Type 是"我发给你的是什么格式",Accept 是"我希望你回给我什么格式"。

常见的 Content-Type

场景
application/jsonREST API(最常见)
application/x-www-form-urlencoded普通表单提交
multipart/form-data含文件上传的表单
text/htmlHTML 页面
text/plain纯文本

FastAPI 不需要你手动解析 Content-Type——它根据类型注解和 Form()/Body()/File() 自动处理。但理解这一层之后,你会明白为什么"上传文件一定要用 multipart/form-data"——因为 JSON 无法内嵌二进制数据,必须用 multipart 的 boundary 机制分段传输。

7. 一次完整请求发生了什么#

POST /api/items 为例:

1. 浏览器构建 HTTP 请求报文(方法、路径、Header、Body)
2. DNS 解析域名 → IP
3. TCP 三次握手
4. TLS 握手(HTTPS)
5. 发送 HTTP 请求报文
6. 服务端接收 → Web Server(Caddy/Nginx)→ ASGI Server(Uvicorn)→ FastAPI
7. FastAPI 解析报文 → 路由匹配 → 校验 → 执行 handler
8. 构建 HTTP 响应报文 → 原路返回
9. 浏览器接收 → 解析 → 渲染

后面我们在 ASGI 协议篇会详细展开第 6-7 步在 Python 里的具体实现。

8. 这一篇在整个 Python Web 体系里的位置#

HTTP 协议(本篇) ← 所有 Web 框架的共同地基
├── Python:FastAPI / Flask / Django
└── Java:Spring Boot / Servlet

理解 HTTP 本身之后,框架的 API 不再是"要背的咒语",而是"协议语义的自然映射"。

专题阅读

PythonWeb

这篇文章属于同一条阅读链。你可以直接在这里切换,不用再回到列表页重新找。

当前进度3 / 16

留言区

留言

欢迎纠错、补充、交流。昵称和评论内容必填;如果你愿意,也可以留下联系方式,仅站主可见。

0

正在加载评论...

0 / 2000

阅读导航

文章目录

当前阅读位置将在这里显示

0 节