内容简介:有两种防止重复提交:1.禁用提交按钮 2. 发出请求令牌/ ID:我们可以在函数调用HTTP请求之前禁用提交按钮,并在完成HTTP响应后再次启用它。该技术对于需要很长时间才能完成的过程(超过5秒)是有效的。由于不耐烦而无法获得结果,用户无法再次单击n'。此外,我们可能会显示一个正在Loading装载进度,以获得良好的体验。
有两种防止重复提交:1.禁用提交按钮 2. 发出请求令牌/ ID:
禁用提交按钮
我们可以在函数调用HTTP请求之前禁用提交按钮,并在完成HTTP响应后再次启用它。该技术对于需要很长时间才能完成的过程(超过5秒)是有效的。由于不耐烦而无法获得结果,用户无法再次单击n'。此外,我们可能会显示一个正在Loading装载进度,以获得良好的体验。
<!DOCTYPE html>
<html lang="en">
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<form name="form-payment" id="form-payment">
...
</form>
<script type="text/javascript">
$('#form-payment').submit(function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
dataType : "json",
contentType: "application/json; charset=utf-8",
url: "#",
data: "{}",
beforeSend: function(){
$('#button-submit').attr('disabled', 'disable');
},
complete: function(){
$('#button-submit').removeAttr('disabled');
},
success: function (data) {
// do your success action
},
error: function () {
// do your error handler
}
});
});
</script>
</body>
在beforeSend 和complete段,我添加“ disable”属性作为开关, (jquery中有专门语句防止二次提交)
重点来了:
Spring Boot中如何发出请求令牌/ ID
这种技术实际上更复杂,更难实现,但是由于一个好的框架(如Spring Boot)使这更容易。在我们开始代码实现之前,让我们先讨论一下这个机制;
- 加载表单页面时,发出新的requestId
- 在调用后端服务之前将已发出的requestId发送到HTTP头
- 后端服务标识requestId是否已注册
- 如果requestId已经注册,那么我们可以将其标记为违规请求
我们来开始代码。这里是我的JavaScript中的示例代码,用于发出新的requestId。
$(document).ready(function () {
var requestId = new Date().getTime(); // <--- issue new requestId every time page laoded
$('#form-payment').submit(function (e) {
e.preventDefault();
$.ajax({
type: 'POST',
dataType : "json",
contentType: "application/json; charset=utf-8",
headers: { "requestId" : requestId }, // <--- add requestId in header
url: "#",
data: "{}",
beforeSend: function(){
$('#button-submit').attr('disabled', 'disable');
},
complete: function(){
$('#button-submit').removeAttr('disabled');
},
success: function (data) {
},
error: function () {
}
});
});
});
这里是我的Spring Boot项目中的示例代码,我创建了一个Interceptor来处理requestId:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class Interceptor implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ViolationInterceptor()).addPathPatterns("/**");
}
public class ViolationInterceptor extends HandlerInterceptorAdapter {
private List<String> requestIds = new ArrayList<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestId = request.getHeader("requestId");
if (requestIds.contains(requestId))
throw new IllegalArgumentException("Violation Request; Reason requestId already registered");
requestIds.add(requestId);
return super.preHandle(request, response, handler);
}
}
}
Exception处理:
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
@ControllerAdvice
public class ExceptionAdvisor {
@ExceptionHandler(IllegalArgumentException.class)
ResponseEntity illegalArgumentExceptionHandler(IllegalArgumentException e){
return ResponseEntity.ok(e.getMessage());
}
}
在此示例中,我使用应用程序内存来存储requestId。对于认真的开发,我建议使用内存数据库,例如Redis。
实际上,我们可以在识别requestId时修改如何发布新令牌和逻辑。因为这个过程非常简单,我们需要一些东西(requestId)来识别已经请求过的东西。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Out of their Minds
Dennis Shasha、Cathy Lazere / Springer / 1998-07-02 / USD 16.00
This best-selling book is now available in an inexpensive softcover format. Imagine living during the Renaissance and being able to interview that eras greatest scientists about their inspirations, di......一起来看看 《Out of their Minds》 这本书的介绍吧!