前端缓存API请求数据
1. 背景
在一些项目中,有时候会出现不同模块重复请求大量相同api接口的情况,特别是在一些功能相似的后台管理页面中。以下面这几个页面为例,每次进入页面都需要请求等大量重复的下拉框数据,下拉框数据短时间内改动不大,但也不能在前端使用静态数据,所以可以考虑在前端进行数据缓存,避免重复请求api。



2. 实现思路
主要有以下3个步骤:
- 初次获取数据,从服务器中请求数据;
- 建立一个映射表,将下拉框数据保存起来,并同时记录该数据的时间戳;
- 后续再次请求时,首先从映射表中查找数据,如果可以查到数据且数据没过期,则直接使用数据,否则重新从服务器中获取数据;
3. 具体实现
3.1 初次获取数据
以下代码中,首先调用 getLocalData 方法查找缓存,如果没找到缓存,就向服务器请求数据(this.$api.task.getCateListAll),获取到数据后用 setLocalData 方法把数据缓存起来。
// 任务类型下拉框数据
// 首先判断是否有缓存
if (!this.getLocalData('cate')) {
/** 初次请求数据 */
await this.$api.task.getCateListAll().then((res) => {
this.m_taskPropOption.cate = this.$u.array.arrToSelect(res.data); // 使用数据
this.m_taskPropDict.cate = this.$u.array.arrToObj(this.m_taskPropOption.cate, "id"); // 使用数据
this.setLocalData('cate'); // 缓存数据
});
}
3.2 建立映射表,缓存数据
缓存数据主要使用了浏览器的API localStorage,如下面代码中 setLocalData 方法,每次从服务器获取数据后,根据 key 将数据保存在 localStorage 中,并且同时记录时间戳,记录时间戳是为了后面检查缓存数据的过期时间:
/** 设置缓存 - 建立映射表 */
setLocalData(key) {
// 缓存数据
localStorage.setItem(`task_${key}_option`, JSON.stringify(this.m_taskPropOption[key])); // 缓存数据
localStorage.setItem(`task_${key}_dict`, JSON.stringify(this.m_taskPropDict[key])); // 缓存数据
localStorage.setItem(`task_${key}_timestamp`, Date.now()); // 记录时间戳
}
3.3 查找缓存数据
根据方法 getLocalData ,首先根据 key 从 localStorage 中查找缓存的时间戳(时间戳是在缓存数据时一起保存的,如果有时间戳,则表示有缓存数据),如果有缓存时间并且判断缓存时间未过期,则进一步从缓存中获取数据给到程序使用:
/** 获取缓存 - 查找映射表 并 检查过期时间 */
getLocalData(key) {
let storageTimestamp = localStorage.getItem(`task_${key}_timestamp`);
let expires = 1000 * 3600; // 有效时间
let timestamp = Date.now(); // 当前时间戳
// 从缓存中取数据(1h内数据)
if (storageTimestamp && (timestamp - storageTimestamp) < expires) {
let option = localStorage.getItem(`task_${key}_option`); // 从缓存中拿到数据给程序使用
let dict = localStorage.getItem(`task_${key}_dict`); // 从缓存中拿到数据给程序使用
this.m_taskPropOption[key] = JSON.parse(option);
this.m_taskPropDict[key] = JSON.parse(dict);
return true;
}
return false;
}
3.4 实现效果
使用缓存前进入页面:

使用缓存后进入页面:

由上图可以看出,使用缓存前进入页面需要请求7个api接口,而缓存了数据之后,进入页面只需要请求3个接口即可,确实起到了减少了请求接口数量的效果。
4. 方案的不足之处及改善
- 本方案首要的不足在于前端无法准确获知数据库中数据的更新时间。目前暂时设置了缓存时间
expires = 3600 * 1000 ms,也就是说1h内数据被更新了的话,前端显示的依然是缓存的旧数据,这一点暂时没想到改善方法。 - 此外,缓存使用了
localStorage API。localStorage的特点是只要不手动清除,数据会一直保存在浏览器端,这样用户就没有办法清除缓存,要改善这一点的话可以换一个全局对象(Vuex)来保存数据,只要页面刷新的话,缓存的数据会被清除。 - 此外,在系统中会有更新这些缓存相关数据的模块,在这些模块中,可以在更新数据之后直接进行缓存数据的清除,等到下次再请求时,程序检查到没有缓存就会直接从服务器请求新的数据,这一定程度改善了前端无法获知数据跟新时间的不足。
前端缓存API请求数据的更多相关文章
- 前端向服务器请求数据并渲染的方式(ajax/jQuery/axios/vue)
原理: jQuery的ajax请求:complete函数一般无论服务器有无数据返回都会显示(成功或者失败都显示数据): return result
- h5-localStorage实现缓存ajax请求数据
使用背景:要实现每次鼠标hover“能力雷达”,则显示能力雷达图(通过ajax请求数据实现雷达图数据显示),所以每次hover都去请求ajax会影响性能,因此这里要用到本地缓存. 实现: 此处是通过传 ...
- idea模拟前端向后台请求数据输出响应结果
tools-httpClient-Test restful web service 通过上述步骤之后出现如下图 1 表示通过哪种方式请求:2 请求数据的地址头部:3 请求数据的除了头部之后的地址:4, ...
- 前端常见的请求数据汇总(GET POST)
前端在请求接口的时候要和后端人员配合好,根据后端提供的接口文档来进行开发,一般请求类型有这几种 1.GET请求 GET请求一般会将数据放到URL后 GET请求对所发信息量的限制是2000个字符 GET ...
- 如何实现Echart不刷新页面,多语言切换下的地图数据重新加载,api请求数据加载,soketed数据实时加载
可视化项目中经常用到ecahrt,各种异步加载,连接socket,多语言切换等问题,现在汇总一下: Ecahrt初始化,全局统一init,可以初始化为0,等待后续数据操作 1.如果是api重新请求,数 ...
- 从API请求数据的方法(主要适用于tp5)
// 从api获取数据,$data是一个数组,默认为空,请求数据的方法可以通用,但是其它说明只适用于tp5 function postData($url,$data=''){ $ch = curl_i ...
- python后端从数据库请求数据给到前端的具体实现
先来贴一窜代码让大家理解前端/后端/数据库的工作原理, 首先简要说明:前端向后端请求数据,后端根据前端请求数据的类别分析其需求,并连接到数据库获取相应数据: 来一段简单的实例代码模拟淘宝商城: 前端代 ...
- Web Api 内部数据思考 和 利用http缓存优化 Api
在上篇<Web Api 端点设计 与 Oauth>后,接着我们思考Web Api 的内部数据: 其他文章:<API接口安全加强设计方法> 第一 实际使用应该返回怎样的数据 ? ...
- 微信小程序如何调用API实现数据请求-wx.request()
前言 微信小程序不存在ajax,那么它是如何实现数据请求功能的呢?在微信中提供了API的调用wx.request(OBJECT),这个是很不错的.下面就讲一下如何请求数据,简单到不行. wx.requ ...
随机推荐
- SpringCloud Sleuth
1.定义 Sleuth(分布式请求链路跟踪):提供了一套完整的服务跟踪解决方案,也兼容zipkin. 参考网址:https://github.com/spring-cloud/spring-cloud ...
- Java 8 中Sort排序原理:
总的来说,java中Arrays.sort使用了两种排序方法,快速排序和优化的合并排序.Collections.sort方法底层就是调用的Arrays.sort方法. 快速排序主要是对那些基本类型数据 ...
- COM技术中的VARIANT and VARIANTARG
VARIANT and VARIANTARG Use VARIANTARG to describe arguments passed within DISPPARAMS, and VARIANT to ...
- eureka server 配置
启动类 import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure. ...
- 翻译:《实用的Python编程》03_05_Main_module
目录 | 上一节 (3.4 模块) | 下一节 (3.6 设计讨论) 3.5 主模块 本节介绍主程序(主模块)的概念 主函数 在许多编程语言中,存在一个主函数或者主方法的概念. // c / c++ ...
- 深入浅出新一代跨平台抓包&调式利器Fiddler Everywhere
什么是Fiddler Everywhere? Fiddler Everywhere is a web debugging proxy for macOS, Windows, and Linux. Ca ...
- 两种常见Content-type的方便理解
application/x-www-form-urlencoded:key=value键值对application/json:{name:"张三"} JSON字符串塞到请求的bod ...
- 2019 GDUT Rating Contest II : Problem G. Snow Boots
题面: G. Snow Boots Input file: standard input Output file: standard output Time limit: 1 second Memory ...
- Flutter,Weex,React Native比较
- solr简明教程
文章目录 安装 启动 创建core 配置core索引MySQL数据 3.2.1 3.2.2 3.2.3 测试定时更新 五.配置中文分词 SolrJ 操作索引的增.删.查 七.通过SolrJ对MySQL ...