Next.js 13.4生产环境Fetch无法获取新增Prisma数据问题排查
问题原因及解决方案
问题原因
生产环境下Next.js会对符合条件的API路由进行静态预渲染:如果GET请求没有依赖动态请求信息(比如查询参数、请求头、用户会话等),也没有显式禁用静态优化,Next.js会在npm run build阶段预先执行该API并缓存响应结果,后续所有请求都会直接返回缓存的旧数据,完全不会触发新的数据库查询。
你的后端代码虽声明了req参数,但全程未使用它,也未配置动态渲染规则,因此被Next.js判定为可静态预渲染的路由,导致新增数据后接口返回的仍是build时的旧数据。前端设置cache: "no-store"仅能控制浏览器缓存,无法绕过Next.js服务器端的静态预渲染缓存。
解决方案
方案1:显式设置路由为动态渲染(推荐)
在API路由文件顶部添加export const dynamic = 'force-dynamic',强制Next.js每次请求都执行该API,不做静态缓存:
import { NextRequest, NextResponse } from "next/server"; import prisma from "@/app/libs/prismadb"; // 强制该路由每次请求都动态执行,禁用静态缓存 export const dynamic = 'force-dynamic'; export async function GET(req: NextRequest) { try { const pdfFiles = await prisma?.pdfFile.findMany(); return new NextResponse(JSON.stringify(pdfFiles)); } catch (error: any) { console.error(error); return new NextResponse(JSON.stringify({ error: error.message }), { status: 500 }); } }
方案2:使用请求对象触发动态渲染
在GET函数中读取req的任意属性(哪怕仅做无意义读取),让Next.js识别到该路由依赖动态请求信息,从而跳过静态预渲染:
export async function GET(req: NextRequest) { // 读取请求URL,触发动态渲染逻辑 const _ = req.url; try { const pdfFiles = await prisma?.pdfFile.findMany(); return new NextResponse(JSON.stringify(pdfFiles)); } catch (error: any) { console.error(error); return new NextResponse(JSON.stringify({ error: error.message }), { status: 500 }); } }
方案3:设置响应头禁用服务器缓存
在返回响应时添加Cache-Control头,告知Next.js及CDN不要缓存该响应:
export async function GET(req: NextRequest) { try { const pdfFiles = await prisma?.pdfFile.findMany(); const response = new NextResponse(JSON.stringify(pdfFiles)); // 禁止所有层级的缓存,每次请求都重新获取数据 response.headers.set('Cache-Control', 'no-store, max-age=0'); return response; } catch (error: any) { console.error(error); return new NextResponse(JSON.stringify({ error: error.message }), { status: 500 }); } }
额外说明
- 开发环境(
npm run dev)中Next.js默认不做静态预渲染,每次请求都会执行API逻辑,这也是开发环境功能正常的原因。 - 前端的
cache: "no-store"可保留,用于防止浏览器缓存旧数据,但核心问题需通过后端配置解决。
内容的提问来源于stack exchange,提问作者senix
相关产品推荐
相关产品推荐

