无法绕过Vercel边缘缓存:Next.js App Router GET请求缓存问题
解决Next.js 13.4.6 App Router GET接口在Vercel上被缓存的问题
针对你遇到的GET /battles接口在Vercel上被持久缓存的问题,以下是几个精准的解决方案,适配App Router和Vercel的缓存机制:
1. 在API路由文件中显式启用动态渲染
App Router的API路由默认是静态优化的,即便设置了响应头,也需要在路由文件中明确声明强制动态执行。注意:该配置要放在**API路由文件(app/battles/route.ts)**内,而非页面组件中:
// app/battles/route.ts import { NextResponse } from 'next/server'; // 假设你的数据库查询函数 import { getRandomTwoEntities } from '@/services/db'; // 强制每次请求都执行路由逻辑,禁止静态缓存 export const dynamic = 'force-dynamic'; export async function GET() { // 确保查询逻辑无内部缓存,每次请求都重新查询数据库 const entities = await getRandomTwoEntities(); return NextResponse.json(entities, { headers: { // 明确告知Vercel和客户端不缓存响应 'Cache-Control': 'no-store, max-age=0, must-revalidate', }, }); }
2. 用revalidate: 0替代动态模式
如果dynamic: 'force-dynamic'未生效,可尝试revalidate: 0,它同样会强制路由每次请求重新执行,且在Vercel环境中能正确绕过边缘缓存:
// app/battles/route.ts import { NextResponse } from 'next/server'; import { getRandomTwoEntities } from '@/services/db'; // 禁止缓存,等同于动态渲染 export const revalidate = 0; export async function GET() { const entities = await getRandomTwoEntities(); return NextResponse.json(entities, { headers: { 'Cache-Control': 'no-store, max-age=0', }, }); }
3. 完善客户端请求的缓存配置
确保客户端fetch请求不会被浏览器缓存,除了设置cache: 'no-store',可添加兼容头强化效果:
// 客户端调用代码 async function fetchBattles() { const response = await fetch('/battles', { method: 'GET', cache: 'no-store', headers: { 'Cache-Control': 'no-store', 'Pragma': 'no-cache', }, }); if (!response.ok) { throw new Error('Failed to fetch battles'); } return response.json(); }
额外排查点
- 检查数据库查询函数是否存在内部缓存:比如部分ORM(如Prisma)或自定义逻辑可能会缓存查询结果,需确保每次GET请求都触发新的数据库查询。
- 查看Vercel函数日志:确认响应头中的
Cache-Control是否正确返回,有时框架或Vercel默认配置会覆盖自定义头。
内容的提问来源于stack exchange,提问作者smg
相关产品推荐
相关产品推荐

