phase 5 part 1: typescript, vue, react, ssr(Next.js 16) topics with lessons, scenarios, interviews, verified examples
This commit is contained in:
1 parent
7a32d2c9a6
commit
7b5cae7d24
39 files changed
+2482
-48
No files matched your search
@@ -0,0 +1,82 @@
|
||||
---
|
||||
id: frontend.ssr.scenario.help-center
|
||||
title: 帮助中心 + 智能客服:SEO、渲染模式组合和 BFF 设计
|
||||
type: scenario
|
||||
domain: frontend
|
||||
stack: [ssr, react, nginx, fastapi]
|
||||
tags: [SEO, SSG, ISR, BFF, 流式接口, 鉴权, CDN 缓存]
|
||||
level: intermediate
|
||||
prerequisites: [frontend.ssr.nextjs-app-router]
|
||||
est_hours: 2.5
|
||||
related: [frontend.ssr.interview, devops.nginx.scenario.ai-gateway-sse-canary]
|
||||
week: [7]
|
||||
---
|
||||
|
||||
# 帮助中心 + 智能客服:SEO、渲染模式组合和 BFF 设计
|
||||
|
||||
## 业务背景与问题
|
||||
|
||||
公司的帮助中心是一个 Vue 单页应用,搜索引擎几乎收录不到文章;新增的智能客服直接从浏览器调用 Python 的 AI 服务,出现:
|
||||
|
||||
1. 帮助文章在搜索引擎中找不到,客服电话量居高不下;
|
||||
2. AI 服务的地址和临时令牌暴露在前端代码中;
|
||||
3. 文章更新后要重新部署整个前端;
|
||||
4. 用户在 CDN 上看到了别人的“我的工单”页面。
|
||||
|
||||
## 约束
|
||||
|
||||
- 文章由运营在 CMS 中维护,每天更新几十篇。
|
||||
- AI 服务(FastAPI + LangGraph)由另一个团队维护。
|
||||
|
||||
## 方案设计
|
||||
|
||||
1. **Next.js 重建帮助中心**:
|
||||
- 文章页:静态生成 + 按时间或 CMS 回调(webhook)按路径重新验证,SEO 好、更新快;
|
||||
- 首页和分类页:静态生成;
|
||||
- “我的工单”:动态渲染,禁止 CDN 缓存(`Cache-Control: private, no-store`);
|
||||
- 智能客服:客户端组件。
|
||||
2. **BFF**:Next.js 的路由处理器作为 BFF,校验用户会话,转发到 AI 服务(服务间凭证只在服务端),透传流式响应;限流防刷。
|
||||
3. **SEO**:每篇文章生成标题、描述、结构化数据;生成站点地图。
|
||||
4. **部署**:Next.js 以 Node 服务部署在 Nginx 后,静态资源走 CDN;Nginx 对 `/api/chat` 关闭缓冲。
|
||||
|
||||
## 关键代码
|
||||
|
||||
BFF 转发流式响应(示意):
|
||||
|
||||
```ts
|
||||
// app/api/chat/route.ts
|
||||
export async function POST(request: Request) {
|
||||
const user = await getSessionUser(request); // 校验登录态
|
||||
if (!user) return Response.json({ error: "未登录" }, { status: 401 });
|
||||
if (!(await rateLimit(`chat:${user.id}`, 20, 60))) return Response.json({ error: "请求过于频繁" }, { status: 429 });
|
||||
const upstream = await fetch(`${process.env.AI_SERVICE_URL}/chat`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${process.env.AI_SERVICE_TOKEN}`, "X-User-Id": user.id },
|
||||
body: await request.text(),
|
||||
signal: request.signal, // 用户断开时取消上游请求
|
||||
});
|
||||
return new Response(upstream.body, { status: upstream.status, headers: { "Content-Type": "text/event-stream", "Cache-Control": "no-cache" } });
|
||||
}
|
||||
```
|
||||
|
||||
可运行的最小项目:[examples/next-ai-chat](../examples/next-ai-chat/)。
|
||||
|
||||
## 取舍
|
||||
|
||||
| 选择 | 优点 | 缺点 |
|
||||
| --- | --- | --- |
|
||||
| **Next.js SSG/ISR + BFF(本方案)** | SEO、性能、安全兼顾 | 多了一个 Node 服务要运维 |
|
||||
| 保持 SPA + 预渲染服务 | 改动小 | 预渲染服务维护麻烦,效果一般 |
|
||||
| Nuxt | 团队熟悉 Vue | 同样可行;选择取决于团队技术栈 |
|
||||
| 浏览器直连 AI 服务 | 少一跳 | 凭证暴露、难以统一鉴权和限流 |
|
||||
|
||||
## 易错点
|
||||
|
||||
- 动态的个人页面被 CDN 缓存。
|
||||
- BFF 把上游的流读完再返回,失去流式效果。
|
||||
- 服务间令牌用 `NEXT_PUBLIC_` 前缀的环境变量(会被打包进浏览器代码)。
|
||||
- CMS 回调触发重新验证的接口没有鉴权。
|
||||
|
||||
## 面试怎么讲
|
||||
|
||||
> “帮助中心我用 Next.js 重做:文章页静态生成,CMS 更新时通过回调按路径重新验证,SEO 和更新速度都解决了;我的工单是动态页面,明确禁止 CDN 缓存。智能客服前端是客户端组件,调用 Next.js 的路由处理器做 BFF:校验会话、限流,用服务端的凭证转发到 Python 的 AI 服务,直接透传流式响应,用户断开时通过 signal 取消上游。”
|
||||
Reference in new issue
Block a user