SpringBoot如何防止重複提交?- Adrian Adendrata
有兩種防止重複提交: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)來識別已經請求過的東西。
相關文章
- 前端如何防止介面重複提交前端
- js 防止重複提交方案JS
- PHP 防止表單重複提交PHP
- 前端防止使用者重複提交-js前端JS
- 防止表單重複提交的程式碼
- jquery防止重複提交程式碼例項jQuery
- PHP防止使用者重複提交表單PHP
- 防止表單重複提交的幾種策略
- 如何使POST請求具有冪等性防止重複提交 - mscharhag
- PHP防止表單重複提交的解決方法PHP
- beego有防止頁面重複提交的功能嗎Go
- 13-Jsp防止二次提交(重複提交) 時間戳JS時間戳
- 前臺防止表單重複提交的方法。Jquery、jsjQueryJS
- 防止重複提交與驗證控制元件配合使用控制元件
- WinForm MDIParent如何防止重複開啟ORM
- 專案分享七:客戶端防止表單重複提交客戶端
- PHP透過session判斷防止表單重複提交例項PHPSession
- 如何防止jQuery物件動畫重複執行jQuery物件動畫
- MQ 如何防止訊息重複入隊MQ
- 防止Toast重複提醒AST
- Java使用Redis實現分散式鎖來防止重複提交問題JavaRedis分散式
- 重複提交,你是如何處理的?
- 分散式重複提交分散式
- axios 重複提交iOS
- 防止表單提交按鈕重複點選現象程式碼例項
- 防止指令碼重複執行方法指令碼
- java 表單避免重複提交?Java
- 關於如何防止重複簽到的技術探討
- jFinal避免表單重複提交
- 關於ajax提交表單,重複提交解決方法
- Spring MVC表單防重複提交SpringMVC
- MySQL防止重複插入相同記錄 insert if not existsMySql
- 重新封裝一個iptables防止規則重複封裝
- Android 防止多次點選,Toast重複顯示AndroidAST
- AJAX防重複提交的辦法總結
- 解決表單重複提交的問題
- strust2 重複提交的問題Rust
- 何為Redis單據鎖,你又是如何防止併發重複寫入的Redis