一、需求描述
在提交表单时,很多时候会因为网路延迟或者后端处理需要一定时间,很容易导致用户重复点击提交按钮,这样会造成很多
二、使用javascript简单实现
- html表单
<form id="sb" action = "/result" method = "POST">
<textarea autocomplete="off" rows="20" cols="155" style="min-height: 21px;" name="txt" ></textarea>
<p><input type = "button" value = "提交" onclick="getSubmitUrl(this)"></p>
</form>
- javascript实现防止重复提交
let is_submit = false;
function getSubmitUrl(self) {
if (!is_submit){
is_submit = true;
document.getElementById("sb").submit();
}
}
三、使用java+redis优雅实现
使用java的注解、面向切面(aop)、redis实现可以跨服务器的防止表单重复提交
- 设置注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NoRepeatSubmit {
int time() default 1_000;
}
- 实现防止重复提交逻辑
@Slf4j
@Aspect
@Component
public class NoRepeatSubmitAop {
@Autowired
RedisUtil redisUtil;
@Around("execution(execute表达式匹配要拦截的方法) && @annotation(noRepeatSubmit)")
public Object doAround(ProceedingJoinPoint pjp, NoRepeatSubmit noRepeatSubmit) {
try {
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
// 根据ip地址、请求路径、请求参数、token等拼接成字符串,作为key值
String key = String.format("REQUEST_FORM_%s_%s_%s_%s", ip, url, args.toString(), token);
// 获得当前时间作为value
long now = System.currentTimeMillis();
// 判断是否重复提交
if (redisUtil.hasKey(key)) {
// 上次表单提交时间
long lastTime = Long.parseLong(redisUtil.get(key));
// 如果现在距离上次提交时间小于设置的默认时间 则 判断为重复提交 否则 正常提交
if ((now - lastTime) < noRepeatSubmit.time()) {
return OperationInfo.failure("请勿重复提交!");
}
}
// 如果不存在key,在redis中新建key-value
redisUtil.setEx(key, String.valueOf(now),1, TimeUnit.MINUTES);
return pjp.proceed();
} catch (EmcsCustomException e) {
return OperationInfo.failure(e.getMessage());
} catch (Throwable e) {
log.error("校验表单重复提交时异常: {}", e.getMessage());
return OperationInfo.failure("校验表单重复提交时异常!");
}
}
}
- 使用示例
// 直接在想要防止重复提交的接口上添加即可
@NoRepeatSubmit
//也可以自定义两次间隔时间
@NoRepeatSubmit(time=2_000)
最后修改时间:2021-08-20 09:52:48
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。