Next.js 14中{ cache: 'no-store' }无法获取Sanity最新数据问题
cache: 'no-store'无法从Sanity获取最新数据的问题排查 问题描述
在Next.js中使用{ cache: 'no-store' }选项时,出现缓存行为异常:按照文档说明该选项应绕过缓存、每次请求动态获取数据,但实际无法从Sanity CMS获取最新内容——已删除的帖子依然显示,新创建的帖子不展示。
使用的代码如下:
const fetchPosts = async () => { const query = `*[_type == "post"] | order(publishedAt desc){ title, slug, publishedAt, mainImage { asset->{ _id, url }, alt }, author->{ name } }`; try { const posts = await client.fetch(query, { cache: 'no-store' }); console.log("Posts fetched:", posts); return posts; } catch (error) { console.error("Sanity fetch error:", error); return []; } };
相反,使用{ next: { revalidate: 3600 } }时能正常获取最新数据。已尝试重启开发服务器、清除缓存、检查响应头,以及切换useCdn = true/false,问题仍存在。
问题根源分析
核心问题是你将Next.js的缓存配置传给了Sanity客户端的fetch方法,而非Next.js原生的fetch函数。Sanity的JavaScript客户端并不识别cache: 'no-store'这个参数,导致该配置完全不生效,数据依然被Sanity客户端或Next.js默认缓存策略处理。
而{ next: { revalidate: 3600 } }是Next.js路由规则能识别的参数,因此可以触发重新验证逻辑,拿到最新数据。
解决方案
方案1:使用Next.js原生fetch调用Sanity API
绕过Sanity客户端,直接用Next.js的fetch请求Sanity API端点,确保cache: 'no-store'配置被正确处理:
const fetchPosts = async () => { const query = encodeURIComponent(`*[_type == "post"] | order(publishedAt desc){ title, slug, publishedAt, mainImage { asset->{ _id, url }, alt }, author->{ name } }`); const projectId = "你的Sanity项目ID"; const dataset = "你的数据集名称"; const apiVersion = "v2023-05-03"; // 使用最新稳定API版本 try { const res = await fetch( `https://${projectId}.api.sanity.io/${apiVersion}/data/query/${dataset}?query=${query}`, { cache: 'no-store' } // 该配置会被Next.js正确解析 ); const { result } = await res.json(); console.log("Posts fetched:", result); return result; } catch (error) { console.error("Sanity fetch error:", error); return []; } };
方案2:配置Sanity客户端的缓存行为
若坚持使用Sanity客户端,可通过以下方式禁用缓存:
全局禁用客户端缓存
初始化Sanity客户端时,设置perspective: 'raw'和useCdn: false,确保直接从Sanity数据库读取最新数据:import { createClient } from '@sanity/client'; const client = createClient({ projectId: '你的项目ID', dataset: '你的数据集', apiVersion: 'v2023-05-03', useCdn: false, // 禁用CDN缓存 perspective: 'raw' // 读取原始未缓存的文档数据 });单请求级禁用缓存
在client.fetch中添加perspective: 'raw'参数,强制获取最新内容:const posts = await client.fetch(query, {}, { perspective: 'raw' });
额外验证步骤
- 打开浏览器开发者工具的
Network标签,检查请求响应头是否包含Cache-Control: no-store - 在生产环境测试,开发环境的Next.js可能存在额外缓存逻辑干扰
内容的提问来源于stack exchange,提问作者Scottsdaaale

