表单重复提交的情况有大致如下几种:
- 用户重复点击提交按钮(异步请求)
- 网络不好,导致用户以为没有点击,所以重复点击了提交(同步请求,转发导致)
- 用户提交表单,转发到另一个页面,然后点击刷新导致重复提交(同步请求,转发导致)
- 用户提交表单,转发到另一个页面,然后点击浏览器返回上一步,接着继续提交表单(同步请求,转发导致)
解决方案:
同步请求:
1、JSP页面生成一个随机值,作为表单唯一id,将这个唯一值放置在Session中,随便在表单中搞一个隐藏域存放这个值,提交表单时,将表单数据和这个唯一值一起提交到后台,然后在后台获取session中保存的唯一值,将后台的session值和前端表单传递过来的唯一值进行比较:
- 前端唯一值id
==
后台唯一值id 表示:第一次表单提交,然后把后台中的session值删除,转发到某个页面。 - 前端唯一值id
!=
后台唯一值id 表示:重复提交的表单,可以重定向到某个页面。
异步请求:
1、大概思路:在前端生成一个随机值,然后传递到后台去,后台使用Aop进行拦截,将随机值作为key,请求数据作为value,存放在redis中,并设置过期时间。aop拦截使用可以自定义一个注解,加载controller方法上。当用户重复点击提交按钮时,会拦截标注了自定义注解的方法,进入aop拦截方法,在环绕通知中进行判断,是否在redis中存在该key,如果存在表示重复提交则返回或者返回原来的数据,不存在则设置进去,并设置过期时间,过期时间可控,在自定义注解中可以自定义方法获取过期时间。
2、发送请求后,使用js将按钮隐藏,或者设置按钮倒计时可以点击。
github:xxx