Next.js API路由使用node-cache读取缓存返回undefined问题
问题原因及解决方案
核心问题:内存缓存的进程隔离
node-cache是内存级缓存,缓存数据仅存在于当前运行的Node.js进程内存中。而Next.js的运行机制导致:
- 开发模式下,页面的
getServerSideProps和API路由会运行在不同的Node.js进程中; - 生产环境如果是Serverless部署(比如Vercel),页面SSR和API路由是独立的函数实例,内存完全不共享。
所以你在getServerSideProps里设置的缓存,只属于页面渲染的进程/实例,API路由访问的是自己进程内的缓存,自然读不到数据,返回undefined。
解决方案
1. 使用共享缓存服务(推荐,生产环境适用)
改用Redis、Memcached这类独立的缓存服务,所有进程/实例都连接同一个缓存服务,实现数据共享。以Redis为例:
步骤1:安装依赖
npm install ioredis
步骤2:修改cache.js
const Redis = require('ioredis'); // 根据你的Redis配置填写参数 const redis = new Redis({ host: 'localhost', // 本地开发用localhost,生产环境填你的Redis服务器地址 port: 6379, // 如有密码,添加 password: '你的Redis密码' }); class Cache { async get(key) { const value = await redis.get(key); // 解析JSON格式的缓存数据 return value ? JSON.parse(value) : null; } async set(key, value, ttl) { // 将数据转为JSON字符串存储,设置过期时间(ttl单位:秒) await redis.set(key, JSON.stringify(value), 'EX', ttl); } } module.exports = new Cache();
这样不管是getServerSideProps还是API路由,都连接同一个Redis实例,缓存数据完全共享。
2. 开发模式临时调试方案(仅本地开发用)
Next.js开发模式下,可以通过修改配置让页面和API路由共用同一个进程,仅适合本地调试,生产环境不生效:
修改next.config.js:
module.exports = { webpack: (config, { isServer }) => { if (isServer) { config.cache = false; } return config; }, };
3. 调整缓存逻辑(不推荐,仅适合无需共享的场景)
如果不需要跨进程共享缓存,可在API路由里也实现相同的缓存设置逻辑,保证API路由能读到自己设置的缓存,但这不是真正的共享方案:
// API路由代码修改 import Cache from '../cache' export default async function handler(req: any, res: any) { const data = {username:'Philip'} let cachedData = await Cache.get('cachedObject'); if(!cachedData){ await Cache.set('cachedObject', data, 10000); cachedData = data; } console.log('cachedDataApi', cachedData) res.status(200).json({ success: true, data: cachedData}); }
原代码小问题修正
原Cache类的set方法没有返回值,你在getServerSideProps里用await Cache.set(...)赋值给cachedData会得到undefined,建议修正逻辑:
// getServerSideProps里的逻辑调整 if(!cachedData){ await Cache.set('cachedObject', data, 10000); cachedData = data; // 直接赋值原数据,而不是set的返回值 }
内容的提问来源于stack exchange,提问作者SuRaj Creator
相关产品推荐
相关产品推荐

