Level 33 / 阅读练习

前后端接口联调

理解接口契约、请求地址、跨域、token、分页、表单提交、错误码和联调排查顺序。

Progress

阅读中

0/2 步完成 / 阅读后完成练习才算通关

Practice

本关怎么过

  • 读完正文后确认完成阅读
  • 完成 1 道选择题练习
  • 答错时看解释,再回到正文补理解

一句话:接口联调就是让前端发出的请求,能被后端正确接住、校验、处理,并把前端看得懂的结果返回来。

本篇学完你会什么:知道接口联调前要约定什么,怎么处理跨域、token、分页、错误码、表单提交,以及出现“前端说传了、后端说没收到”时该怎么查。

1. 接口联调到底在联什么

前端和后端就像两个人配合办事。

前端负责:

收集用户输入
组织请求参数
发送请求
展示返回结果
展示错误和 loading

后端负责:

接收请求
校验参数
检查登录和权限
处理业务
读写数据库
返回结果或错误

接口联调不是“请求能发出去”就完了,而是要确认每一步都对得上。

2. 先约定接口契约

接口契约就是前后端先说清楚:

要约定什么例子
请求方法GET / POST / PUT / DELETE
请求路径/api/v1/users
请求参数pagepage_sizekeyword
请求体usernameemailrole_ids
返回数据itemstotal
错误格式codemessage
是否要登录要不要带 token
需要什么权限user:readuser:create

比如用户列表可以约定成:

GET /api/v1/users?page=1&page_size=20&keyword=tom
Authorization: Bearer <token>

返回:

{
  "items": [
    {
      "id": 1,
      "username": "tom",
      "email": "tom@example.com",
      "is_active": true
    }
  ],
  "total": 1
}

3. 请求地址和环境怎么处理

开发时最常见的问题是:前端请求地址写错。

建议分三层:

例子说明
前端代码里request.get('/users')只写业务路径
请求封装里baseURL: '/api/v1'统一加 API 前缀
开发代理里/api -> http://localhost:8000转发到后端

不要在每个页面里到处写:

fetch('http://localhost:8000/api/v1/users')

更推荐:

request.get('/users', { params: query })

这样以后从本地切到测试环境,只改请求封装或环境变量,不用全项目搜索替换。

4. 跨域是什么

跨域就是浏览器发现:

前端页面在 localhost:3000
后端接口在 localhost:8000

它会问:这个前端有没有资格请求这个后端?

后端需要允许来源:

app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

开发环境也可以用前端代理绕开跨域:

浏览器 -> 前端开发服务器 /api -> 后端 localhost:8000

大白话:跨域不是后端接口坏了,而是浏览器在替用户把门。

5. token 怎么带

登录后拿到 token:

{
  "access_token": "eyJxxx"
}

前端请求拦截器统一加请求头:

request.interceptors.request.use((config) => {
  const token = getToken();

  if (token) {
    config.headers.Authorization = `Bearer ${token}`;
  }

  return config;
});

后端用依赖读取:

async def get_current_user(
    credentials: HTTPAuthorizationCredentials = Depends(security),
):
    token = credentials.credentials
    payload = decode_access_token(token)
    return await get_user_by_id(int(payload["sub"]))

联调时如果接口一直 401,先看浏览器 Network:

Request Headers 里有没有 Authorization
Authorization 是不是 Bearer 开头
token 有没有过期
后端 JWT_SECRET 有没有变

6. 列表分页怎么对齐

前端常用:

type UserQuery = {
  page: number;
  page_size: number;
  keyword?: string;
};

后端接:

@router.get("/users")
async def list_users(
    page: int = 1,
    page_size: int = 20,
    keyword: str | None = None,
):
    ...

返回建议固定:

{
  "items": [],
  "total": 0,
  "page": 1,
  "page_size": 20
}

不要一会儿叫 list,一会儿叫 records,一会儿叫 data。一个项目里统一就好。

7. 表单提交怎么对齐

前端表单:

type UserFormValue = {
  username: string;
  email: string;
  password?: string;
  role_ids: number[];
  is_active: boolean;
};

后端 Schema:

class UserCreate(BaseModel):
    username: str
    email: EmailStr
    password: str
    role_ids: list[int] = []
    is_active: bool = True

重点看字段名:

前端字段后端字段是否一致
usernameusername一致
roleIdsrole_ids不一致,需要转换
isActiveis_active不一致,需要转换

如果前端用驼峰、后端用下划线,要么在请求前转换,要么后端 Schema 支持 alias。不要靠记忆临时猜。

8. 错误码怎么对齐

建议后端错误尽量清楚:

HTTP 状态码大白话前端怎么处理
400参数不对显示表单错误
401没登录或 token 失效跳登录页
403没权限显示无权限
404数据不存在提示记录不存在
409数据冲突提示用户名重复
500服务内部错误提示稍后再试

前端不要只写:

请求失败

最好能根据错误信息告诉用户下一步:

用户名已存在,请换一个。
登录已失效,请重新登录。
你没有删除用户的权限。

9. 联调排查顺序

遇到问题时,按这条链路查:

1. 页面状态对不对
2. Network 里请求有没有发出去
3. 请求 URL、method、headers、payload 对不对
4. 后端接口有没有收到
5. 后端参数校验有没有过
6. 权限和 token 有没有过
7. 数据库查询或写入有没有成功
8. 返回格式前端能不能解析

不要一上来就猜“是不是框架 bug”。多数联调问题都在 URL、字段名、token、错误格式这几处。

10. 常见错误

错误表现修正
前端 URL 写死换环境就坏统一 baseURL
忘带 token后端 401请求拦截器统一加 Authorization
字段名不一致后端收不到值对齐命名或做转换
前端只看 200错误体验很差根据状态码分别处理
后端返回格式不统一前端到处写兼容统一响应契约
CORS 配错浏览器拦截配 allow_origins 或开发代理
分页字段不统一表格页码错乱固定 items/total/page/page_size

11. 联调检查清单

[ ] 接口文档里有 method、path、params、body、response
[ ] 前端请求 baseURL 统一
[ ] 本地开发代理能转发到后端
[ ] 需要登录的接口带 Authorization
[ ] 401403409500 有不同处理
[ ] 列表返回 items 和 total
[ ] 表单字段名和后端 Schema 对齐
[ ] 删除、修改等危险操作有权限校验
[ ] Network 能看到真实 payload
[ ] 后端日志能查到请求和错误原因

12. 总结表

名词大白话
接口契约前后端约好的请求和返回格式
baseURL所有接口的统一前缀
CORS浏览器的跨域安全检查
Authorization放 token 的请求头
payload前端真正发出去的数据
Network浏览器里看请求真相的地方
401没登录
403没权限
409数据冲突,比如用户名重复

上一篇建议:大白话讲解——从 0 到 1 做一个用户管理系统.md

下一篇建议:大白话讲解——后台权限系统设计.md

Checkpoint

读完后做题闯关

先读正文,再用下面的选择题检查自己是否真的理解。答错会出现解释,可以回到正文补一眼再重选。

0/1
先完成阅读

读完正文后点击“我已读完,进入练习”,题目会变成可答状态。

第 1 题

读完这一篇后,最适合怎么确认自己真的理解了?