CHAPTER 8 · FRONTEND INTEGRATION
08
后端接口在 Postman 中返回 200,为什么 React 页面还是拿不到数据?
Postman 成功只能说明后端接口在某个请求条件下可用。浏览器页面是否成功,还取决于请求地址、代理、Token、字段结构和前端状态处理。
三个常见现象
接口能通,不等于页面能用。
Postman 请求成功
React 请求失败
登录成功并拿到 Token
查询相册仍然返回 401
前端运行在 5173
后端运行在 8080
浏览器提示跨域
先问清楚这些问题
Postman 成功能证明什么?
浏览器和 Postman 有什么不同?
前端请求实际发到了哪里?
Token 是否正确携带?
前端读取的字段和后端返回的一致吗?
AI 生成的代码能运行,结构就一定合理吗?
联调成功 = 接口正确 + 请求正确 + 代理正确 + 身份正确 + 数据结构正确
第一步
先用 Postman 隔离后端问题。
如果 Postman 都不能正确调用接口,先不要急着改 React。前端页面只会把问题变得更分散。
登录接口
- 请求地址是否正确
- 是否使用 POST
- 请求体是否是 JSON
- 成功状态码是什么
- 错误密码返回什么
- 响应里 Token 字段叫什么
相册列表接口
- 是否携带 Authorization
- 是否使用 Bearer 格式
- 分页参数是否正确
- 空列表返回
[]还是null - Token 无效时返回什么
- 真实字段名是否记录下来
AI 任务描述
让 AI 写前端前,先给它完整接口契约。
请使用 React、Vite 和 TypeScript,为现有相册后端开发前端页面。
后端接口:
1. POST /api/login
2. GET /api/my/albums?page=1&pageSize=20
统一响应结构:
{
"code": "OK",
"message": "success",
"data": {}
}
要求:
1. 登录成功后保存 accessToken。
2. 请求相册接口时携带 Bearer Token。
3. 使用 TypeScript,禁止使用 any。
4. API 请求不能直接散落在页面组件中。
5. 页面必须处理加载、空数据和错误状态。
6. 所有后端请求使用 /api 相对路径。
7. 不要在代码中写死 localhost:8080。
8. 不要修改 Go 服务端的跨域配置。AI 生成代码的质量,很大程度取决于输入是否包含完整接口契约和工程约束。不要只说“帮我做一个相册前端”。
项目结构
前后端可以放在同一个练习项目里,但职责要分清。
album-system/
├── backend/
│ ├── cmd/
│ ├── internal/
│ ├── migrations/
│ └── go.mod
├── frontend/
│ ├── src/
│ ├── package.json
│ ├── tsconfig.json
│ └── vite.config.ts
└── README.md这样做的好处是:一次打开完整项目,便于对照前后端接口,也便于 AI 同时读取两侧代码。正式项目中,前端和后端可能会拆成不同仓库、不同构建方式和不同发布流程。
frontend/src/
├── api/
│ ├── request.ts
│ ├── auth.ts
│ └── albums.ts
├── components/
│ ├── AlbumCard.tsx
│ ├── Loading.tsx
│ └── ErrorMessage.tsx
├── pages/
│ ├── LoginPage.tsx
│ └── AlbumListPage.tsx
├── types/
│ ├── api.ts
│ ├── auth.ts
│ └── album.ts
├── App.tsx
└── main.tsx不要把登录、请求、Token、相册列表和错误处理全部写进 App.tsx。
TypeScript 审查
TypeScript 类型必须对齐真实响应。
AI 定义
items: Album[]
后端实际返回
items: null
是否把类型改成 Album[] | null
如果接口约定空列表返回数组,应优先修复后端响应。
是否大量使用 any
any 会让类型检查失去价值,也会掩盖字段层级错误。
时间字段是否先用 string 接收
可以JSON 返回的是字符串,前端需要格式化时再转换。
接口设计约定为空数组时,应修复后端,不要为了兼容错误响应不断放宽前端类型。
请求封装
请求逻辑不要散落在每个页面里。
错误示例
fetch("http://localhost:8080/api/my/albums")写死后端地址
错误换环境就要改代码,也会绕过开发代理。
直接请求 8080
错误浏览器会发起跨域请求,问题不再经过 Vite Proxy。
统一使用 /api
开发阶段交给 Vite Proxy 转发,上线阶段交给统一入口处理。
Vite Proxy
开发阶段,让浏览器只请求 5173。
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react()],
server: {
proxy: {
"/api": {
target: "http://localhost:8080",
changeOrigin: true,
},
},
},
});localhost:5173/api/my/albums ↓ Vite 开发服务器 ↓ 代理转发 Go 后端
localhost:8080/api/my/albums
前端代码统一使用 /api。修改 vite.config.ts 后需要重启 Vite。Vite Proxy 只存在于开发环境,不是正式上线方案。
不要这样解决联调
不要为了方便,直接开放 Go 服务端任意跨域。
本章约定
React → /api
↓
Vite Proxy
↓
Go 后端
不要这样做
React
↓ 直接跨域
Go 后端允许所有 Origin
不要把它当作联调方案
Access-Control-Allow-Origin: *开放跨域不等于绕过 JWT,但不能把允许任意来源当作解决联调问题的方法。CORS 不能替代认证和权限控制,非浏览器客户端也不会受到浏览器 CORS 的保护。
Network 排错
页面失败时,先看浏览器到底发了什么请求。
这个请求返回 401,优先看身份凭证。
先检查 Authorization 请求头是否存在,格式是否是 Bearer <token>,Token 是否过期。不要先去改 MySQL 索引、CSS 或 Vite 主题配置。
问题定位
Postman 成功,React 出现跨域错误,先改哪里?
开发阶段优先检查请求路径和 Vite Proxy。
如果 Postman 能调通,而 React 页面出现跨域错误,通常不是 MySQL、JWT 算法或页面样式的问题。先确认前端是否使用 /api 相对路径,以及 vite.config.ts 是否正确代理到 Go 后端。
AI 代码审查
能跑起来之后,还要看结构和边界。
项目结构
API 请求是否与页面组件分离?类型是否集中定义?是否把全部代码写进 App.tsx?组件是否拆分过度?
TypeScript
是否使用 any?请求和响应是否有类型?是否存在大量无依据类型断言?类型是否符合真实响应?
请求逻辑
是否使用 /api?是否统一携带 Token?是否判断 HTTP 状态码?是否处理加载、空数据和错误状态?
安全与配置
是否写死后端地址?是否把 JWT Secret 写入前端?是否要求修改 Go CORS?是否添加了任意跨域?
fetch("http://localhost:8080/api/my/albums");这行代码至少包含四个问题:写死环境地址、绕过 Vite Proxy、可能触发浏览器跨域、没有经过统一请求封装。
本章总结
- React 开发前,应先用 Postman 验证后端接口。
- Postman 成功不代表浏览器页面一定成功。
- 前端页面可以由 AI 快速生成,但接口契约和工程约束必须给清楚。
- 项目结构用于分离页面、组件、API 和类型。
- TypeScript 不能代替真实网络响应验证。
- 前端请求统一使用
/api相对路径。 - 开发阶段由 Vite Proxy 转发到 Go 服务。
- 不要通过开放任意跨域解决联调问题。
- Network 面板是前后端联调最重要的排查工具之一。
- 当前前后端放在同一个练习项目里,是为了方便本地开发和对照接口。
Vite Proxy 只存在于开发环境,正式上线后谁来转发/api?
下一章进入前后端构建、Nginx 和正式发布链路。