看不见的护盾:全量 API 代理
在传统 Headless CMS 架构中,前端直接调用 WordPress REST API——这意味着你的后端地址暴露在每一个网站访客的浏览器 Network 面板中。本项目的做法截然不同——Nitro 服务端接管了所有外部通信:
浏览器 → /api/graphql → Nitro 服务端 → WordPress(内网/白名单)
浏览器 → /api/salong/v1/* → Nitro 服务端 → WordPress
浏览器 → /api/wp/v2/* → Nitro 服务端 → WordPress三个代理端点覆盖了全部后端通信路径:
| 代理端点 | 用途 | 特殊能力 |
|---|---|---|
/api/graphql | GraphQL 查询/变更 | SHA-256 缓存、请求去重、自动重试、认证透传 |
/api/salong/v1/* | 自定义 Salong API | 通用代理透传 |
/api/wp/v2/* | WordPress REST API | 通用代理透传 |
浏览器中只能看到 /api/graphql,永远看不到 wp-admin 或 wp-json——这对安全性的提升是根本性的。
认证隔离:JWT 绝不触碰前端
用户登录后,WordPress 颁发的 JWT Token 存储在服务端 Cookie 中,前端代码无需、也无法访问这个 Token。当 GraphQL 端点收到请求时:
// 服务端从 Cookie 中提取 Token
const token = getCookie(event, 'salong_auth_token')
// 注入 Authorization 头转发给 WordPress
headers['Authorization'] = `Bearer ${token}`前端只知道「我已登录」,但 Token 对 JavaScript 完全不可见——即使网站被 XSS 攻击,攻击者也拿不到认证凭据。
GraphQL 缓存引擎:三层防护
/api/graphql 端点内置了一套精密的缓存体系:
第一层:SHA-256 响应缓存。 每个公开查询的结果被 SHA-256 哈希后存入 Nitro Storage,TTL 可配置(默认 120 秒)。同一查询在有效期内的所有请求直接命中缓存,不触碰 WordPress。
第二层:飞行中请求去重。 当缓存未命中时,如果有 100 个用户同时请求同一数据,传统架构会向 WordPress 发起 100 次请求。这里通过 createInFlightRequestPool 将并发请求合并为一次上游调用,其余 99 个请求「搭便车」。
第三层:LRU 缓存预算控制。 缓存不是无限制的。cache-budget.mjs 实现了一套 LRU 淘汰算法——当缓存条目超过 500 条或总字节数超过 32MB,按「最久未使用」原则自动淘汰旧条目。
请求韧性:自动重试与非关键降级
上游 WordPress 可能偶发 429 限流或临时故障。request-resilience.mjs 提供了两组工具:
runWithRetry:针对关键请求(如页面数据),自动重试 429 错误,指数退避延迟。默认重试 1 次,间隔 150ms 起步。
runNonCriticalAsync:针对非关键请求(如侧边栏热门文章),遇到 429 直接使用预设的降级数据,不阻塞页面渲染。
错误安全:绝不泄露堆栈
所有代理端点统一使用 normalizeApiError 处理异常:
export function normalizeApiError(err, fallbackMessage, fallbackStatusCode) {
const statusCode = getStatusCode(err) ?? fallbackStatusCode
const msg = String(getMessage(err) || fallbackMessage)
return createError({ statusCode, statusMessage: msg })
}用户永远只能看到干净的 HTTP 状态码和简短消息。任何服务器堆栈跟踪、WordPress 内部错误信息、数据库连接字符串都不会泄露到前端。
Sitemap 动态生成与智能缓存
/sitemap.xml 端点从 WordPress API 动态拉取站点地图数据,自动生成标准 XML:
// 常规访问:缓存 10 分钟,CDN 复用 1 小时
'Cache-Control': 'public, max-age=600, s-maxage=3600, stale-while-revalidate=86400'
// 手动刷新(?refresh=1):跳过所有缓存
'Cache-Control': 'no-store, no-cache, must-revalidate, max-age=0'配合自定义 XSL 样式表(/sitemap.xsl),站点地图在浏览器中直接以美观的表格呈现,而非原始 XML。
Nitro 构建优化
// nuxt.config.ts - nitro 配置
nitro: {
minify: true,
preset: 'node-server',
compressPublicAssets: {
gzip: true,
brotli: true
},
routeRules: {
'/_nuxt/**': { isr: 600, headers: { 'Cache-Control': 'max-age=31536000, immutable' } },
'/api/**': { cors: true, headers: { 'Cache-Control': 'no-store' } }
}
}minify: true:服务端代码压缩,减少冷启动时间gzip + brotli:双层压缩,静态资源传输体积减少 70%isr: 600:nuxt 构建资源缓存 10 分钟immutable:静态资源永久缓存,文件名 hash 保证更新时自动失效
总结
这套 Nitro 服务端架构用三道防线保护了 WordPress 后端:
- 访问隔离:所有 API 请求通过代理,后端地址从不暴露
- 认证隔离:JWT Token 仅存服务端 Cookie,前端不可见
- 信息隔离:错误信息统一过滤,堆栈跟踪永不泄露
同时通过 SHA-256 缓存、飞行中去重、LRU 预算控制和智能重试,在不牺牲可靠性的前提下将 WordPress 负载降到最低。这是一道真正的「隐形护盾」——用户感知不到它的存在,但每一毫秒的性能和每一比特的安全都由它保障。



