如何实现JS数据缓存,让跨设备用户均可访问有效期30天的付费API缓存数据
纯前端JS无法实现跨设备跨用户的共享缓存,所有前端本地存储方案(localStorage、IndexedDB等)都仅对当前设备当前浏览器生效,其他用户无法访问。你可以用JS生态的Node.js搭建中间代理层实现需求,完全符合接口方30天缓存的要求,具体实现如下:
实现方案
1. 技术选型
- 服务端用Node.js,属于JS技术栈,符合开发语言要求
- 缓存存储优先选Redis,自带过期时间配置能力,不需要手动开发过期删除逻辑,性能足以支撑高并发请求
- 小流量场景可以用文件缓存+定时任务的轻量方案,不需要额外部署Redis服务
2. 核心代理服务实现
第一步:安装依赖
使用express框架开发,执行命令安装所需包:npm install express redis axios
第二步:编写代理服务代码
const express = require('express'); const redis = require('redis'); const axios = require('axios'); const app = express(); // 配置缓存过期时间为30天,单位为秒 const REDIS_CACHE_EXPIRE = 30 * 24 * 60 * 60; // 初始化Redis客户端 const redisClient = redis.createClient({ // 填入你的Redis服务配置 host: '127.0.0.1', port: 6379 }); redisClient.connect(); // 统一代理接口 app.get('/api/proxy', async (req, res) => { try { // 按请求参数生成唯一缓存key,区分不同请求的缓存内容 const cacheKey = `paid_api_${Buffer.from(JSON.stringify(req.query)).toString('base64')}`; // 优先读取缓存 const cachedRes = await redisClient.get(cacheKey); if (cachedRes) { return res.json(JSON.parse(cachedRes)); } // 无缓存时请求付费API const apiRes = await axios.get('你的付费API接口地址', { params: req.query, headers: { // 付费API要求的鉴权头信息 } }); // 写入缓存并设置30天过期 await redisClient.setEx(cacheKey, REDIS_CACHE_EXPIRE, JSON.stringify(apiRes.data)); // 返回数据给前端 res.json(apiRes.data); } catch (err) { res.status(500).json({ code: 500, msg: '请求失败' }); } }); app.listen(3000, () => { console.log('代理服务已启动,端口3000'); });
第三步:前端调用逻辑
所有用户的前端JS直接请求你部署的代理接口即可,不需要直接调用付费API:
async function fetchData(params) { const res = await fetch('https://你部署的代理服务域名/api/proxy', { method: 'GET', params: params }); return res.json(); }
3. 合规性注意事项
- 严格按接口方要求设置30天过期时间,不要额外开发缓存数据的永久备份逻辑
- 定期校验缓存过期规则是否生效,避免出现超期存储的情况
- 若使用文件缓存替代Redis,需要额外编写每日定时任务,扫描并删除存储时间超过30天的缓存文件
4. 低流量场景轻量替代方案
如果访问量极低不想部署Redis,可以直接用Node.js内存缓存实现,注意服务重启后缓存会丢失:
const cacheMap = new Map(); // 30天的毫秒值 const CACHE_EXPIRE_TIME = 30 * 24 * 60 * 60 * 1000; // 每小时清理一次过期缓存 setInterval(() => { const now = Date.now(); for (const [key, value] of cacheMap.entries()) { if (now - value.cacheTime > CACHE_EXPIRE_TIME) { cacheMap.delete(key); } } }, 3600 * 1000);
内容的提问来源于stack exchange,提问作者Rodion Pyatigroskiy
相关产品推荐
相关产品推荐

