当前位置:首页 > 技术文章 > 正文内容

解决 Next.js 部署后 API 缓存不刷新的问题

zonemu2个月前 (08-05)技术文章35

问题背景

本地开发中,直接访问 /api/chatsessions 能实时获取 PostgreSQL 的最新数据。但部署至服务器跑 PM2、Nginx 反代后,却始终返回旧内容,数据库更新后网页依旧不刷新。


排查步骤

1. 确认 Route Handler 类型

/api/chatsessions 是 App Router 的 Route Handlerroute.ts ),默认是动态的,但仍可能使用 数据缓存(Data Cache) ,导致返回旧数据 Medium Medium+11nextjs.org+11Stack Overflow+11 。


2. dynamic = 'force-dynamic' 不足以清缓存

#技术分享 #掘金虽然在 Handler 顶部写了 export const dynamic = 'force-dynamic' ,它只关闭“完整路由缓存”(Full Route Cache),但不影响数据缓存 nextjs.org+4Reddit+4Stack Overflow+4 。


3. 缺少 fetchCache = 'force-no-store'

官方说明:需同时添加 export const fetchCache = 'force-no-store'default-no-store ,才能跳过 Data Cache,确保每次请求都刷新数据 nextjs.org+1Medium+1 。


4. 注意斜杠跳转问题

访问 /api/chatsessions 会自动 308 跳转到 /api/chatsessions/ 。若前端和 Nginx 路径不一致,可能导致缓存配置失效。


解决方案

export const dynamic = 'force-dynamic';
export const fetchCache = 'force-no-store';

import { NextResponse } from "next/server"; import { Pool } from "pg";

const pool = new Pool({ connectionString: process.env.DATABASE_URL });

export async function GET() { const client = await pool.connect(); try { const { rows } = await client.query(` SELECT id, created_at FROM chats ORDER BY created_at DESC LIMIT 50 `); const sessions = rows.map(r => ({ id: r.id, createdAt: r.created_at })); return NextResponse.json(sessions, { headers: { 'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0' } }); } finally { client.release(); } }
  • dynamic = 'force-dynamic' :禁用完整路由缓存
  • fetchCache = 'force-no-store' :禁用数据缓存,即 Data Cache
  • 在返回头中加入 Cache-Control: no-store :防止浏览器或代理缓存

辅助配置:Nginx 与前端请求

Nginx 配置

location ^~ /api/ {
  proxy_pass         http://127.0.0.1:3000;
  proxy_cache        off;
  proxy_buffering    off;
  add_header Cache-Control "no-store, max-age=0" always;
}

前端 fetch 示例

await fetch('/api/chatsessions/', { cache: 'no-store' });

确保 API 路径统一带斜杠,避免 308 重定向带来的缓存问题。


验证方法

  1. 修改数据库内容后,使用 curl -i https://.../api/chatsessions/ 查看响应头是否带 Cache-Control: no-store
  2. 访问接口并刷新页面,应立即获取最新数据。

总结

  • Next.js Route Handler 默认仍使用数据缓存,需要配合使用 dynamic + fetchCache 才能彻底关闭;
  • 保证 API 路径带斜杠,防止跳转时走代理缓存;
  • 全链路禁缓存保障(路由层 + Handler + Nginx + 前端),即可实现“每次请求都实时更新”。

--- 这篇记录了从问题定位到解决完整流程,希望能帮助遇到同样问题的同学。

相关文章

Vue父子组件参数传递方法(vue父子组件传参方式)

在 Vue 中,父子组件之间的参数传递是常见的需求,主要通过 Props 和 自定义事件 实现。以下是详细说明和代码示例:一、父组件向子组件传递参数(Props)父组件通过 属性 向子组件传递数据,子...

使用GitLab实现CICD(gitlab配置cicd)

GitLab CI/CD 是一个内置在GitLab中的工具,用于通过持续方法进行软件开发:Continuous Integration (CI) 持续集成Continuous Delivery (C...

Java教程:GitLab在项目的环境搭建和基本的使用

gitlab-使用入门1 导读本教程主要讲解了GitLab在项目的环境搭建和基本的使用,可以帮助大家在企业中能够自主搭建GitLab服务,并且可以GitLab中的组、权限、项目自主操作GitLab简介...

2个将HTML5打包成app的方法(h5打包成android)

越来越多的开发者热衷于使用html5+JavaScript开发移动Web App。不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数。那么,有什么办法,既可以使用H...

使用HTML5+JS实现文字转语音(h5 文字转语音)

使用HTML5+JS实现文字转语音现在越来越多的视频采用了AI语音,下面给大家介绍几种简单的文字转语音的办法,完全免费的欧。使用HTML5语音合成API-SpeechSynthesis实现的文字转语音...

育知HTML5培训,为什么要学习“HTML5混合式开发技术”

HTML5 的广泛应用,强势崛起企业现在安卓、iOS开发人员都在学习HTML5混合开发,节约成本、一专多能是未来很多企业用人趋势!HTML5工程师在今后的工作中与 Android、iOS工程师对接的几...