缓存策略核心是为读多写少、时效可控的API设计带过期时间的本地内存缓存,需规范生成缓存键、精确控制expiresAt、支持命中/过期/未命中三类逻辑,并兼顾安全性与内存管理。

缓存策略的核心目标
减少重复请求、降低服务端压力、提升响应速度。关键不是“一律缓存”,而是对读多写少、时效性可控的 API 做有生命周期的本地缓存,避免脏数据和无限堆积。
设计带过期的请求缓存器要点
需同时管理:请求参数 → 缓存键、响应数据 + 过期时间、缓存命中与失效判断。不依赖外部存储(如 Redis),纯内存实现更轻量,适合客户端或中间层单实例场景。
-
缓存键生成:用请求方法 + URL + 规范化查询参数(如排序 key)+ JSON 序列化请求体(GET 无 body,POST 需考虑)生成唯一字符串,推荐用
JSON.stringify或哈希(如 xxHash)防长键膨胀 -
过期控制:每个缓存项记录
expiresAt时间戳(毫秒),而非 TTL。查缓存时只比对当前时间,不启动定时器清理,避免内存泄漏和定时任务干扰 - 缓存更新逻辑:命中且未过期 → 直接返回;命中但过期 → 异步刷新(stale-while-revalidate)或同步重发(按业务定);未命中 → 发起请求,成功后写入缓存并设过期时间
一个可运行的 JavaScript 缓存器示例
以下为浏览器或 Node.js 环境可用的轻量实现(无第三方依赖):
class ExpiringAPICache {
constructor(defaultTTL = 5 * 60 * 1000) { // 默认 5 分钟
this.cache = new Map();
this.defaultTTL = defaultTTL;
}
<p>_generateKey(method, url, params = {}, body) {
const sortedParams = Object.keys(params)
.sort()
.reduce((o, k) => ({ ...o, [k]: params[k] }), {});
return <code>${method.toUpperCase()}|${url}|${JSON.stringify(sortedParams)}|${body ? JSON.stringify(body) : ''}</code>;
}</p><p>get(key) {
const item = this.cache.get(key);
if (!item) return undefined;
if (Date.now() > item.expiresAt) {
this.cache.delete(key);
return undefined;
}
return item.data;
}</p><p>set(key, data, ttl = this.defaultTTL) {
this.cache.set(key, {
data,
expiresAt: Date.now() + ttl
});
}</p><p>async fetch(url, options = {}) {
const { method = 'GET', headers = {}, body, cacheTTL } = options;
const params = new URLSearchParams(new URL(url).search);
const key = this._generateKey(method, url.split('?')[0], Object.fromEntries(params), body);</p><pre class="brush:php;toolbar:false;">const cached = this.get(key);
if (cached !== undefined) return Promise.resolve(cached);
try {
const res = await fetch(url, { method, headers, body });
const data = await res.json();
this.set(key, data, cacheTTL ?? this.defaultTTL);
return data;
} catch (err) {
throw err;
}} }
// 使用示例 const apiCache = new ExpiringAPICache(30 * 1000); // 30 秒过期 apiCache.fetch('/api/user/123').then(console.log); // 首次请求走网络 apiCache.fetch('/api/user/123').then(console.log); // 30 秒内直接返回缓存
进阶建议与注意事项
真实场景中还需考虑:
- 错误响应是否缓存:默认不缓存 4xx/5xx,但可配置(如 404 缓存 10 秒防刷)
-
请求头影响缓存:如
Authorization、Accept-Language应参与 key 生成,否则多用户共享缓存会出错 - 内存清理机制:长期运行需限制最大条目数(LRU)或定期扫描过期项(非高频调用时可省略)
-
与 HTTP 缓存协同:服务端设置
Cache-Control: public, max-age=60时,前端缓存 TTL 不应超过该值

















