我们在项目中都会遇到这样的情况,当进入某个页面,通过点击创建按钮创建系统的一个模块。在你点下按钮时api请求已经发出,此时如果再次点击这个按钮,若不做任何处理,那么这个api请求就又会触发一次。即此时发送了两个相同的请求,这便是我们不想看到的结果。解决这个问题有很多种方法:比如在按钮点击时,禁用该按钮直到这个请求的后台返回数据,再放开禁用的按钮。但这个方法有个问题就是,如果你的项目中有很多地方需要做处理,那么你就会需要在各个地方都做一下这样的处理,导致工作量加大,也都是写重复枯燥的步骤。
因此我在这介绍另一种方案,即通过vue router 的拦截器去实现。大致逻辑是:首先点击按钮,此时拦截器会拦截到api请求的request,判断当请求是post请求时,通过传递过来的参数,使用MD5加密的方式将参数加密成一个唯一的签名字符串。通过这个签名字符串来判断请求是否是来自同一个api。将签名存在session中,借此来判断是否是短时间内单个api的多次请求。
当请求发出时,我们同时将签名字符串存在请求的request herders中发送给后台。这时候也就需要后台配合一下,让后台开发人员将我们传过去的签名字符串在response headers再次返回给我们。这么做的原因是因为:当这次请求已经返回数据时,我们要将原先禁止同个api再次请求的限制给去除。通过后台返回的签名,我们就可以知道应该将那个api放开限制。
注意:不论是请求超时,还是请求出错,都应该将缓存中的签名数组给清空,不然会导致下次无法再次请求该接口。
MD5加密生成签名的方法:
这里是将签字字符串传入到request headers中,然后后台再将它放在response headers中返回回来。从而实现判断是否完成了一次api的请求。如果不想将签字字符串传入后台,也可以自己定义一个定时器。比如设置一个5秒的定时器,5秒内如果这个签字字符串出现了两次以上,则只发送一次该请求,也可以控制做到等待请求完整结束后再可以发出该请求。但是这样有一个问题,就是这事定时器的时间无法确定,因为接口请求的速度和网络有很大关系,无法保证接口就一定能够在你设置好的定时内就完成请求,所以在这我用了另外的方法。
一次完整的api请求中,签名字符串传入、返回的过程: