80 lines
4.9 KiB
Markdown
80 lines
4.9 KiB
Markdown
# 页面健康检查报告
|
||
|
||
> 检查日期:2026-09-10 · 方式:启动 Django 后端(sqlite 开发库)+ Vite dev server,浏览器逐条访问全部 73 条前端路由,检测 Django 404 劫持 / 白屏 / Vite 错误遮罩 / 渲染内容
|
||
> 桌面端(1366×900)73 条全覆盖;移动端视口(390×844)抽查 5 条;SPA 内部导航 1 条
|
||
|
||
---
|
||
|
||
## 结论:不是全部正常。核心问题是「前端路由与 API 代理前缀冲突」,直接访问(刷新/分享链接)22 条路由在开发环境打开的是后端响应
|
||
|
||
**关键背景**:SPA 内部点击导航**不受影响**(客户端路由不经过代理,实测从首页点击"文章资源"正常打开 `/articles`)。**受影响的是直接加载 URL**——用户刷新页面、收藏链接、分享链接、或从外部点进来时触发。
|
||
|
||
---
|
||
|
||
## 一、问题清单
|
||
|
||
### 1.1 开发环境(vite 代理前缀匹配过宽):22 条路由被劫持
|
||
|
||
vite 代理用**前缀匹配**,`'/api'` 连 `/api-docs`、`/api-detail/x` 一起劫持;`'/s'` 连 `/settings`、`/shorturl-detail`、`/system-message` 一起劫持。
|
||
|
||
| 被劫持路由 | 命中的代理前缀 | 实际返回 |
|
||
|---|---|---|
|
||
| /api、/api-directory、/api-docs、/api-detail/1、/api-detail/baidu-translate、/api-detail/currency | `/api` | Django 404 |
|
||
| /api/ip-location、/api/password-generator、/api/qrcode-generator、/api/weather-details、/api/air-quality-details | `/api` | Django 404 |
|
||
| /articles、/article/1、/article-editor、/article-manage | `/article` | Django 404 |
|
||
| /learn、/learn-editor、/learn-manage | `/learn` | Django 404 |
|
||
| /user | `/user` | Django 200(返回后端 JSON `{"code":200,"message":"User API index"}`,更迷惑) |
|
||
| /user/1 | `/user` | Django 404 |
|
||
| /bug、/bug-detail | `/bug` | Django 404 |
|
||
| /chat | `/chat` | Django 404 |
|
||
| /history | `/history` | Django 404 |
|
||
| /messages | `/message`(前缀误伤) | Django 404 |
|
||
| /settings、/shorturl-detail、/system-message | `/s`(前缀误伤) | Django 404 |
|
||
| /search | `/search` | Django 200(原始 JSON 直接显示在页面上) |
|
||
| /tool-detail | `/tool`(前缀误伤) | Django 404 |
|
||
|
||
### 1.2 生产环境(nginx 正则带尾斜杠 `^/(api|user|article|...)/`):7 条路由被劫持
|
||
|
||
尾斜杠要求使 `/api-docs` 这类"前缀 + 非斜杠"路由幸免,但**子路径路由**在生产依然命中:
|
||
|
||
- `/api/ip-location`、`/api/password-generator`、`/api/qrcode-generator`、`/api/weather-details`、`/api/air-quality-details`(5 条数据 API 页面)
|
||
- `/article/1`(文章详情页——核心页面!)
|
||
- `/user/1`(用户主页)
|
||
|
||
**生产环境影响面虽小,但被劫持的恰好是文章详情和用户主页这类核心分享场景。**
|
||
|
||
### 1.3 非问题(确认正常)
|
||
|
||
- **73 条路由全部无白屏、无 Vite 错误遮罩、无组件崩溃**;渲染失败的只有上述被代理劫持的。
|
||
- 十余个"只显示导航栏"的路由(/utility/base64、/qrcode-generator、/profile 等)为**登录守卫慢渲染**,延长等待后正常显示登录引导或页面内容,非缺陷。
|
||
- `/agreement` 首次访问白屏是 dev server 首次编译懒加载块超时,重测正常(生产构建无此问题)。
|
||
- 移动端视口抽查 5 条(/、/utility、/utility/json-formatter 等)渲染正常,isMobile 分支组件树工作正常。
|
||
- `/course-learn` 无参数时显示"缺少章节参数"为预期空态。
|
||
- 404 兜底路由(`*`)工作正常。
|
||
|
||
---
|
||
|
||
## 二、修复建议(按优先级)
|
||
|
||
### 方案 A(推荐,改前端路由,一劳永逸)
|
||
把与 API 前缀冲突的 7 条生产受影响路由改名:
|
||
- `/api/*` → `/open-api/*`(或 `/api-market/*`)
|
||
- `/article/:id` → `/article-detail/:id`(或 `/post/:id`)
|
||
- `/user/:id` → `/user-home/:id`(已有 `/user-home` 路由可复用)
|
||
同步修改所有 `navigation()` 跳转代码。工作量约半天,含全量回归。
|
||
|
||
### 方案 B(改代理,保住现有 URL)
|
||
- **vite**:把宽前缀换成精确正则(如 `^/api/(?!detail|docs|directory)`),仅代理真正的 API 路径——开发环境立即修复,但生产 nginx 仍需同步改写。
|
||
- **nginx**:把 `^/(api|user|...)/` 改为仅匹配真实存在的 API 路径列表(枚举 `/api/weather/` 等),给前端子路径路由让路。改动集中但需要逐条核对后端 URL 清单,漏一条就是线上事故。
|
||
|
||
**建议 A**:URL 是前端资产,趁早改比 API 上线后改便宜;`/article/:id` 在生产被劫持说明这个冲突已经真实咬人。
|
||
|
||
---
|
||
|
||
## 三、检查方法备注
|
||
|
||
- 后端:Django runserver :8002(sqlite 开发库 + seed_tools 数据)
|
||
- 前端:vite dev :5173(代理目标 8002)
|
||
- 检测逻辑:每路由检查 ① 是否 Django 404/JSON 响应(代理劫持)② #root 是否空(白屏)③ vite-error-overlay(编译错误)④ 正文长度
|
||
- 局限:SPA 内部导航仅抽样验证 1 条;登录态页面(任务中心/钱包等)以未登录态检查;移动端为抽查非全量。
|