Vercel Serverless GET接口返回陈旧数据,添加缓存头无效求助
问题:Vercel Serverless GET端点返回陈旧KV数据,缓存头配置无效
我有一个Vercel Serverless的GET端点函数,从KV中获取值并返回内容。代码如下:
export async function GET() { const db = await kv.get<DbInfo>(DB_KEY); const info = <do some transformation here>; return NextResponse.json( { data: info ?? {} }, { status: 200 }, ); }
该函数在本地开发时完全正常,部署到Vercel后仅首次调用能返回正确数据,后续所有调用均返回首次获取的陈旧数据,即使KV中的数据已更新。
我怀疑是缓存问题,添加了缓存头配置:
return NextResponse.json( { data: info ?? {} }, { status: 200, headers: { 'Cache-Control': 'public, s-maxage=1', 'CDN-Cache-Control': 'public, s-maxage=10', 'Vercel-CDN-Cache-Control': 'public, s-maxage=10', }, }, );
但这毫无作用。在Postman中查看响应头,Cache-Control和CDN-Cache-Control已按设置生效,但Age字段持续增加至数分钟,数据仍处于陈旧状态。
我另有一个逻辑基本相同但会校验请求头中鉴权令牌的端点,该端点运行完全正常。为何此接口仅在Vercel部署后会返回如此陈旧的数据?是否有遗漏的配置项?
解决方案与分析
Vercel自动缓存的特殊性:Vercel会对无动态参数、无用户特定上下文的GET请求触发自动函数缓存,这种缓存优先级高于你设置的缓存头。而带鉴权令牌的端点因为请求头包含用户唯一令牌,属于个性化请求,不会被自动缓存,所以能正常返回最新数据。
强制禁用函数级缓存:在你的GET函数上方添加
export const dynamic = 'force-dynamic',这会强制Vercel每次请求都执行函数逻辑,跳过自动缓存。配合更严格的缓存头彻底禁止缓存:
export const dynamic = 'force-dynamic'; export async function GET() { const db = await kv.get<DbInfo>(DB_KEY); const info = <do some transformation here>; return NextResponse.json( { data: info ?? {} }, { status: 200, headers: { 'Cache-Control': 'no-store, no-cache, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' }, }, ); }
- 禁用KV读取缓存:Vercel KV默认开启读取缓存,可能导致函数读取到本地缓存的旧数据。在
kv.get时添加{ cache: 'no-store' }参数,强制从KV存储获取最新值:
const db = await kv.get<DbInfo>(DB_KEY, { cache: 'no-store' });
- 缓存头优先级说明:Vercel环境中
Vercel-CDN-Cache-Control优先级高于CDN-Cache-Control,但仅靠缩短s-maxage无法突破自动函数缓存,必须配合dynamic = 'force-dynamic'才能彻底解决问题。
内容的提问来源于stack exchange,提问作者mt_xing
相关产品推荐
相关产品推荐

