NUXT 3 SSR动态路由搭配Cloudflare缓存的实现方案咨询
解决Nuxt 3(SSR)电商站点动态路由Cloudflare缓存全链路方案
一、Cloudflare端缓存规则配置
- 创建缓存规则,匹配动态路由路径(比如
/[a-z0-9-]+,根据你的slug格式调整),排除API接口、静态资源路径(如/api/*、/_nuxt/*) - 设置缓存策略:
- 缓存级别:缓存一切
- 边缘缓存TTL:根据业务需求设置(比如86400秒/1天)
- 浏览器缓存TTL:设为0,强制浏览器每次请求都走Cloudflare验证缓存
- 开启缓存键完整性,确保不同路由的缓存独立(若需忽略utm等参数,可在缓存键设置中排除)
- 注意:对404/500等错误响应,设置不缓存或极短TTL(比如60秒)
二、Nuxt 3端缓存头配置(让Cloudflare识别可缓存内容)
在server/middleware/cache.ts中添加中间件,验证slug有效性并设置对应缓存头:
export default defineEventHandler(async (event) => { const path = getRequestPath(event) // 仅处理动态路由(排除静态资源、API、根路径) const slugMatch = path.match(/^\/([a-z0-9-]+)$/) if (!slugMatch || path.includes('.') || path === '/') return const slug = slugMatch[1] // 调用外部API验证slug是否存在 const slugExists = await fetch(`https://your-api-domain.com/check-slug/${slug}`) .then(res => res.ok) if (slugExists) { // 允许Cloudflare缓存,浏览器不直接缓存 setResponseHeaders(event, { 'Cache-Control': 'public, max-age=0, s-maxage=86400', 'Vary': 'Accept-Encoding' }) } else { // 无效slug返回404,禁止缓存 setResponseHeaders(event, { 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Expires': '0' }) event.response.status = 404 } })
三、解决应用内导航重复Fetch问题
应用内导航默认走SPA模式,会重新执行数据请求,需调整数据获取逻辑复用缓存:
- 用
useAsyncData结合路由路径作为缓存键,设置与Cloudflare一致的缓存有效期:
<script setup> const route = useRoute() // 以路由路径为缓存键,缓存有效期和Cloudflare s-maxage同步 const { data: pageData } = useAsyncData(route.path, async () => { const res = await fetch(`/api/fetch-page/${route.params.slug}`) return res.json() }, { cache: true, maxAge: 86400000 // 单位:毫秒,对应1天 }) </script>
- 若需严格复用Cloudflare缓存的HTML(放弃SPA导航体验),可将应用内导航改为硬跳转:
<template> <a @click.prevent="navigateToSlug(item.slug)"> {{ item.name }} </a> </template> <script setup> const navigateToSlug = (slug) => { window.location.href = `/${slug}` } </script>
四、缓存清除机制(内容更新时触发)
当页面/分类/产品内容更新时,需同时清除Cloudflare缓存和Nuxt端缓存:
- 在Nuxt中创建缓存清除API端点
server/api/purge-cache.ts:
export default defineEventHandler(async (event) => { const { slug } = await readBody(event) const targetUrl = `https://your-domain.com/${slug}` // 1. 调用Cloudflare Purge API清除对应URL缓存 await fetch(`https://api.cloudflare.com/client/v4/zones/${process.env.CLOUDFLARE_ZONE_ID}/purge_cache`, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ files: [targetUrl] }) }) // 2. 清除Nuxt Nitro服务器端缓存(若启用) if (event.context.nitroApp.cache) { await event.context.nitroApp.cache.delete(`page:${slug}`) } return { success: true } })
- 在你的CMS/内容管理系统中,添加内容更新的钩子事件,调用上述API触发缓存清除。
易忽略的关键点
- 404缓存防护:务必验证slug有效性后再设置缓存头,避免缓存无效路由的404页面
- 缓存键一致性:确保Cloudflare缓存键包含完整路由路径,避免不同路由共享缓存
- 客户端缓存同步:可添加全局版本号机制(如在
app.vue中请求版本接口),当服务器版本更新时,自动清除客户端useAsyncData缓存 - Nitro缓存增强:若部署在Cloudflare Workers,可启用Nitro的Cloudflare KV缓存,让Nuxt直接将渲染结果缓存到Cloudflare KV,进一步减少SSR重复渲染
内容的提问来源于stack exchange,提问作者nhatimme
相关产品推荐
相关产品推荐

