fetch获取JSON后如何正确存储到localStorage实现本地缓存?
问题根因
- 直接对
fetch返回的Response对象做序列化是无效的:Response是浏览器内置的流对象,包含很多不可序列化的内部属性,直接JSON.stringify就会得到空对象 response.json()是异步方法,会返回一个Promise对象,需要等待Promise完成才能拿到实际的JSON数据,直接打印自然是pending状态
修复后的完整实现
你需要先拿到解析完成的JSON数据再存入localStorage,同时建议给每个请求ID分配独立的缓存key,避免不同请求的缓存互相覆盖:
// 每个请求ID对应独立的缓存key,避免冲突 const cacheKey = `api_cache_${id}`; // 读取本地缓存 const cachedData = localStorage.getItem(cacheKey); if (cachedData) { // 缓存存在,先解析为JSON对象再渲染 try { const data = JSON.parse(cachedData); createHTML(data); } catch (e) { // 缓存内容损坏时, fallback到请求逻辑 fetchApiAndCache(id, cacheKey); } } else { // 无缓存,直接发起请求 fetchApiAndCache(id, cacheKey); } // 封装请求+缓存逻辑 function fetchApiAndCache(id, cacheKey) { fetch(url + id) .then(response => { // 先校验请求是否成功 if (!response.ok) throw new Error('接口请求异常'); // 异步解析响应流为JSON return response.json(); }) .then(data => { // 拿到数据后先序列化存入缓存 localStorage.setItem(cacheKey, JSON.stringify(data)); // 再执行渲染逻辑 createHTML(data); }) .catch(error => { console.error('请求失败:', error); }) }
额外注意事项
- localStorage最大存储容量仅为5MB左右,如果你的JSON数据体积较大,可能会存储失败,建议存之前做容量校验,或者改用IndexedDB存储大体积数据
- 建议给缓存加过期时间,避免长时间使用过期的旧数据,可以在存缓存的同时存储一个时间戳,读取时判断是否超过有效期,超过则重新发起请求
- 读取缓存时一定要加
try/catch捕获JSON解析错误,避免缓存内容损坏导致页面逻辑中断
内容的提问来源于stack exchange,提问作者Smithy
相关产品推荐
相关产品推荐

