第 10 章 · 前后端协作

前端每个请求穿过网络到后端,后端读写数据库再把数据送回。

10.1 前后端分离

传统服务端渲染:后端拼好 HTML 直接返回。现代前后端分离:前端只负责界面与交互,通过 HTTP API 向后端取数据:

浏览器(前端 SPA,第 8 章框架构建)
   │  HTTP 请求(JSON)
   ▼
后端服务(API)
   │  SQL / ORM
   ▼
数据库(存用户、订单等)
  • 好处:前端后端独立开发、独立部署、独立扩容。
  • 代价:首屏要等 JS 加载再渲染(SPA),多一层网络往返,需配合 SSR/预渲染优化。

10.2 HTTP 与 REST API

前端用 fetch 走 HTTP(见「计算机网络」),REST 是主流 API 风格:

fetch("/api/users/1", { method: "GET" })          // 查
fetch("/api/users", { method: "POST", body: JSON.stringify({ name: "Tom" }) })  // 增
fetch("/api/users/1", { method: "PUT", body: JSON.stringify({ name: "Jerry" }) })  // 改
fetch("/api/users/1", { method: "DELETE" })       // 删
方法语义幂等
GET读资源
POST创建资源
PUT/PATCH整体/局部更新
DELETE删除资源
  • REST 用 URL 表示资源、HTTP 方法表示操作,返回 JSON;状态用状态码(200/400/401/404/500)表达。
  • 幂等 = 重复执行不产生额外副作用(GET 重复读无害,POST 重复会插两条)。

对比:REST 面向资源(URL+方法+状态码),RPC 面向动作(过程调用)。资源型业务用 REST,内部高频调用常选 RPC(gRPC)。

10.3 跨域 CORS

浏览器同源策略:协议+域名+端口都相同才「同源」。跨域请求被浏览器拦截(是浏览器限制,非服务器):

前端 https://app.com  →  请求 https://api.com/user   ← 跨域

后端用 CORS 响应头放行:

Access-Control-Allow-Origin: https://app.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
  • 简单请求直接发,浏览器看响应头判断放行;预检请求(OPTIONS)先问「允许吗」再发真请求。
  • 前端本地开发用 Vite 代理(第 9 章)把 /api 转发到后端,规避跨域。
  • CORS 是「浏览器替用户把关」,后端必须配合;它防的是别人网站冒用你登录态,而非阻止服务器收请求。

10.4 鉴权:Cookie vs Token

HTTP 无状态,每次请求都要带身份凭证:

# Cookie 方案:浏览器自动带上
GET /api/me
Cookie: session_id=abc123

# Token 方案:手动放请求头
GET /api/me
Authorization: Bearer eyJhbGciOi...
Cookie + SessionToken(JWT)
存储浏览器自动带 cookie前端显式存(localStorage/内存)
状态服务端存 session无状态,签名自包含
跨域受同源策略限制手动加 Authorization,跨域灵活
注销服务端删 session 即失效难立即失效(需黑名单/短过期)

对比:Cookie/Session 状态在服务端、跨域麻烦;Token(JWT)无状态、适配前后端分离与跨域,但难即时吊销。现代 SPA 多用 Token。

10.5 一条请求的完整旅程

  1. 用户点击按钮 → DOM 事件(第 5 章)触发处理函数;
  2. 函数里 fetch(第 7 章)发出 HTTP 请求,带上 Token;
  3. 请求经 DNS/TCP/TLS(计算机网络)到达后端;
  4. 后端验 Token → 查数据库(数据库课程)→ 返回 JSON;
  5. 浏览器收到响应,更新框架状态(第 8 章),视图自动刷新;
  6. 整个过程中,前端源码由 git/npm/vite(第 9 章)管理构建,浏览器按第 6 章的流水线渲染。