Next.js 14.2.8生产环境API缓存异常:掷骰子接口重复请求无更新
生产环境下Next.js掷骰子API请求被缓存,无法更新数据
开发模式下掷骰子API运行正常,但生产构建后,首次请求的数据会被缓存,再次调用API时页面数据无法更新。
掷骰子API代码
import { NextResponse } from 'next/server'; export async function GET(request: Request) { const diceRollCalc = (min: number, max: number): number => { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1) + min); }; const result = diceRollCalc(1, 6); const response = NextResponse.json(result); response.headers.set('Cache-Control', 'no-cache, no-store, must-revalidate'); return response; }
调用API的React客户端组件代码
'use client' import { useEffect, useState } from 'react'; function DiceRoll() { const [data, setData] = useState<number | null>(null); useEffect(() => { const fetchData = async () => { const response = await fetch('/api/diceRoll', { cache: 'no-store', headers: { "Cache-Control": "no-cache, no-store, must-revalidate", "Pragma": "no-cache", "Expires": "0", } }); const result = await response.json(); setData(result); }; fetchData(); }, []); const handleButtonClick = async () => { const response = await fetch('/api/diceRoll'); const result = await response.json(); setData(result); }; return ( <div> {data && <p>结果: {data}</p>} <button onClick={handleButtonClick}>掷骰子</button> </div> ); } export default DiceRoll;
页面组件代码
import React from 'react'; import DiceRoll from './diceRollClient'; export default function DicePage() { return ( <div id='main'> <h1>掷骰子</h1> <DiceRoll/> </div> ); }
开发模式与生产模式响应头对比
开发模式
Connection: keep-alive Keep-Alive: timeout=5 Transfer-Encoding: chunked cache-control: no-cache, no-store, must-revalidate content-type: application/json vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch
生产模式
Connection: keep-alive Keep-Alive: timeout=5 Transfer-Encoding: chunked cache-control: no-cache, no-store, must-revalidate content-type: application/json vary: RSC, Next-Router-State-Tree, Next-Router-Prefetch x-nextjs-cache: HIT
问题原因与解决方案
问题核心是按钮点击时的fetch请求未设置缓存控制参数,Next.js生产环境默认会缓存GET请求,即使API返回了no-cache响应头,客户端请求如果没有明确禁用缓存,仍会命中Next.js的内置缓存(表现为x-nextjs-cache: HIT)。
解决方法
修改客户端fetch请求
在按钮点击的fetch调用中添加缓存禁用配置,和useEffect中的请求保持一致:const handleButtonClick = async () => { const response = await fetch('/api/diceRoll', { cache: 'no-store' }); const result = await response.json(); setData(result); };仅设置
cache: 'no-store'即可,该参数会直接告诉Next.js不要缓存此请求。在API路由中强制禁用缓存
在API路由代码顶部添加revalidate: 0配置(Next.js 13+ App Router适用),确保API每次请求都重新执行:import { NextResponse } from 'next/server'; export const revalidate = 0; // 强制禁用缓存 export async function GET(request: Request) { // ... 原有代码 }
两种方式结合使用,可彻底避免生产环境下的缓存问题。
内容的提问来源于stack exchange,提问作者Notorious
相关产品推荐
相关产品推荐

