最近闲来无事,喜欢听大佬水群,他们说道面试的一个题目,接口幂等性问题,由于自己工作中也遇到过,以前并没有好的办法解决,听到一个好用的方法,于是决定记下来。
什么事幂等性,网上的说法很详细了,我的理解就是由于对于curd中的增删改来说的重复调用,查询本来就遵循幂等性原则,反映在接口上,就是由于网络延迟,用户操作等造成多次访问一个借口,导致多次调用的问题。
大佬的比较经典:用户对于同一操作发起的一次请求或者多次请求的结果是一致的,不会因多次点击而产生副作用。
解决方案
1.拿简单的表单验证来说
this.$store.commit('setSerialNO', new Date().getTime());
前端每次调用后端接口,都会携带一个时间戳SerialNO,该值为当前时间戳,该值有前端生成,当请求返回结果时,将用户的setSerialNO更新为最新的时间戳,代表下次用户再请求这个接口,就不是重复操作了。对于新增和修改接口,后端一般会加一个拦截器,专门判断次请求是否是无效请求(重复请求),具体操作如下:
每次后台拿到SerialNO,都会去redis里去拿之前用户存的时间戳作比较,如果查询为空,或者时间戳不相等,代表服务已经返回,说明是新一轮的请求。
如果相同,代表服务器未返回结果,他重复提交了,抛出异常,前端忽略这次请求,请求结束。
2.前端请求后端接口,后端生成时间戳,存在redis里,并把时间戳放在响应里发送给前端,下次请求到来,带上该时间戳,去redis查询,如果存在,后端删除redis里的时间戳并更新。
3.前端请求后端接口,后端根据token每一次生成automicInteger,并存入redis中,如果新请求生成的automicinteger大于redis中上一次请求中存的的automicinteger,则返回结果,如果该值小于redis中上一次请求中存的的automicinteger,则忽略这次请求。
本人菜鸟一枚,以上纯属个人见解,如有错误,欢迎大家指正。