勇闯前后端:后端基础------HTTP与REST
什么是 HTTP、请求/响应结构
核心概念(简明)
- HTTP(超文本传输协议)是 Web 上最常用的应用层协议,用来在客户端与服务器之间交换"消息"。它是客户端---服务器模型、无状态(stateless)通信的基础。(MDN Web Docs)
- HTTP 用"消息"(message)来表示通信:请求 (request)由客户端发出,响应 (response)由服务端返回。消息在 HTTP/1.x 表示为可读的多行文本(请求行/状态行 + header + body);HTTP/2 则把这些消息二进制帧化以提高性能,但语义一致。(MDN Web Docs)
请求的组成(请求行 → 头 → 体)
- 请求行:
<METHOD> <Request-URI> <HTTP-Version>,例如GET /index.html HTTP/1.1。 - 请求头(Headers):
Host,User-Agent,Accept,Content-Type,Authorization等。头承载元信息(路由、内容类型、缓存指令等)。 - 请求体(Body):可选,通常用于 POST/PUT/PATCH 等携带 JSON、表单或二进制数据的请求。
响应的组成(状态行 → 头 → 体)
- 状态行:
HTTP/1.1 200 OK(包含协议版本、状态码、短文本)。 - 响应头(Headers):
Content-Type,Content-Length,Cache-Control,Set-Cookie等。 - 响应体(Body):服务器返回的实体(HTML、JSON、图片等)。
只需要记住
- 请求行/状态行是"第一行"很重要 ------ 能立刻看出方法、目标与结果。
- Headers 决定"如何处理"与"如何缓存/鉴权",Body 才是"实际数据"。
常用 HTTP 方法(verbs):语义、幂等、何时用
方法一览(重点)
GET:获取资源的表示(安全、幂等,通常无请求体)。HEAD:与GET相同但不返回 body(只要头),常用于检查缓存/长度。POST:向资源提交实体(创建/触发副作用),非幂等(重复提交可能产生多份/多次副作用)。PUT:用请求体"完全替换"目标资源(幂等:同样请求重复多次结果相同)。PATCH:对资源执行部分更新(语义为"修改",通常非完全替换)。DELETE:删除资源(幂等:重复删除后资源仍然不存在)。OPTIONS:查询目标资源支持哪些通信选项(CORS preflight 常见)。
(以上方法与它们是否安全/幂等等细节,参考 MDN 方法页。)(MDN Web Docs)
幂等 vs 安全(易混淆点)
- 安全(safe) :不会改变服务器状态(例如
GET,HEAD)。 - 幂等(idempotent) :对同一请求重复多次,服务器状态不再变化(例如
PUT,DELETE是幂等;POST通常不是)。
注意:安全 ≠ 幂等 (GET是两者;PUT幂等但不一定"安全")。
何时用 POST vs PUT(常见困惑)
- 创建资源(服务器分配 ID)→
POST /todos(客户端不提供完整资源 URI)。 - 创建或替换(客户端知道要写入的资源 URI,或用 PUT 语义替换)→
PUT /todos/123(用请求体替换 /todos/123)。 - 局部更新 →
PATCH /todos/123(只提交变更字段)。
实操练习(curl 示例)
GET 静态 JSON:
bash
curl -i https://jsonplaceholder.typicode.com/todos/1
POST 带 JSON body:
bash
curl -i -X POST https://jsonplaceholder.typicode.com/posts \
-H "Content-Type: application/json" \
-d '{"title":"hello","body":"world","userId":1}'
DELETE(对 mock server / 本地 server):
bash
curl -i -X DELETE http://localhost:3000/todos/3
状态码与错误处理:快速记忆表与场景
-
1xx信息(临时) -
2xx成功(常见:200/201/204) -
3xx重定向 -
4xx客户端错误(400/401/403/404/409/422 等) -
5xx服务器错误(500/502/503 等)(详见 MDN 状态码页)(MDN Web Docs)
-
200 OK:请求成功(并返回 body)。 -
201 Created:资源已创建(常跟 Location 头告诉新资源 URI)。 -
204 No Content:操作成功但无响应体(常用于 DELETE、成功的 PUT)。 -
400 Bad Request:请求语法或参数错误(通俗的"请求不合规范")。 -
401 Unauthorized:缺少/错误的认证信息(需要登录/Token)。 -
403 Forbidden:认证了但无权限(禁止访问)。 -
404 Not Found:资源不存在。 -
409 Conflict:请求会导致资源冲突(例如并发更新导致的版本冲突)。 -
422 Unprocessable Entity:请求格式正确但语义无法处理(常用于验证失败)。 -
500 Internal Server Error:服务器内部错误(非预期异常)。 -
502/503:网关错误/服务不可用(下游服务失败或维护中)。
实践:观察真实 API
- 例:访问不存在的 GitHub 用户(观察浏览器或 curl 的返回状态及页面内容),你会看到
404。练习时记录响应头与 body,注意Content-Type与错误结构。(MDN Web Docs)
错误处理建议(API 设计角度)
- 统一错误响应结构(
{ "error": {"code": 422, "message":"xxx", "details":[...]}})。 - 404 与 401/403 区分清楚(认证 vs 授权)。
- 使用 4xx 表示客户端问题,5xx 表示服务器问题;提供机器可解析的
error.code以便客户端 UI 友好展示。
JSON 结构与常见坑(必须掌握的细节)
JSON 语法要点(容易出错)
- 字符串必须用双引号 (
"name":"Alice"),单引号非法。 - 对象/数组尾部不能有多余的逗号 (
{"a":1,}会报错)。 - 支持的值类型:
string,number,object,array,true|false,null。 - JSON 本质上是文本(UTF-8 常用),序列化/反序列化分别为
stringify/parse(或语言对应 API)。(MDN Web Docs)
Python:序列化 / 反序列化
python
import json
data = {"id":1, "title":"buy milk", "done": False}
# 序列化
s = json.dumps(data) # -> JSON 字符串
# 反序列化
obj = json.loads(s) # -> Python dict
print(type(obj), obj["title"])
Java(示例,使用 Jackson)
java
// 需要 com.fasterxml.jackson.databind.ObjectMapper
ObjectMapper mapper = new ObjectMapper();
Map<String,Object> todo = Map.of("id", 1, "title", "buy milk", "done", false);
String json = mapper.writeValueAsString(todo); // 序列化
Map<?,?> parsed = mapper.readValue(json, Map.class); // 反序列化
常见坑 & 排查技巧
- 后端返回
Content-Type: text/html导致前端无法按 JSON 解析 → 检查响应头。 - Unicode/编码问题:确保服务器以
UTF-8返回并在 header 标注。 - 大数(JS 中 Number 精度)→ 对于大整型 ID 考虑用字符串返回,或用 bigint 支持。
- 缺失字段/新增字段向后兼容:设计 API 时尽量使用可选字段与默认值策略。(MDN Web Docs)
REST 风格与资源建模(概念与设计练习)
什么是 REST / RESTful(核心要点)
- REST = Representational State Transfer,是一种架构风格(Roy Fielding 提出),强调资源导向、统一接口、无状态、可缓存、分层系统等约束。REST 不是具体协议,而是用 HTTP 的语义来表达资源操作的一种最佳实践
常见 REST 原则(实用版)
- 资源以名词表示(
/users,/todos/123),不要把动作放在 URI(如/getUser)。 - 使用 HTTP 方法表达动作(GET → 读取,POST → 创建,PUT → 替换,PATCH → 局部更新,DELETE → 删除)。
- 无状态(每个请求应包含处理这个请求所需的全部信息)。
- 使用合适的状态码表达结果(参见 Day 3)。
- 利用
Location头在创建后返回新资源 URI(201 Created)。 - 可选:HATEOAS(通过超链接让客户端发现资源),在很多实际服务中很少完整实现,但理念值得知道
设计示例:一个简单 Todo 服务(5 条 URI 与对应方法)
GET /todos--- 列表(可分页、可筛选)POST /todos--- 创建新 todo(请求体 JSON:{title, due, done}),返回201 Created+Location: /todos/{id}GET /todos/{id}--- 获取单项PUT /todos/{id}--- 完整替换(幂等)PATCH /todos/{id}--- 局部更新(例如只改done字段)
(权限、分页、过滤、排序等是进阶设计要素)
Reference
- MDN --- HTTP 概览、HTTP 消息。(MDN Web Docs)
- MDN --- HTTP 请求方法(Methods)。(MDN Web Docs)
- MDN --- HTTP 状态码(Status)。(MDN Web Docs)
- MDN --- 使用 JSON(Learn Web Development)。(MDN Web Docs)
- Roy Fielding --- REST(原始论文 / 章节,推荐读绪论与约束章节)。(UC Irvine 信息与计算机科学学院)
- RESTfulAPI.net(实务层面介绍与例子)。(REST API Tutorial