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
- 如何防止使用者重複提交訂單?(上)
- 如何防止使用者重複提交訂單?(下)
- 如何防止使用者重複提交訂單?(中)
- Struts2防止表單重複提交
- 前端防止使用者重複提交-js前端JS
- PHP防止使用者重複提交表單PHP
- 如何使POST請求具有冪等性防止重複提交 - mscharhag
- WinForm MDIParent如何防止重複開啟ORM
- PHP透過session判斷防止表單重複提交例項PHPSession
- 如何避免表單的重複提交?
- axios 重複提交iOS
- MQ 如何防止訊息重複入隊MQ
- Java使用Redis實現分散式鎖來防止重複提交問題JavaRedis分散式
- 重複提交,你是如何處理的?
- 分散式重複提交分散式
- jFinal避免表單重複提交
- java 表單避免重複提交?Java
- Spring MVC表單防重複提交SpringMVC
- MySQL防止重複插入相同記錄 insert if not existsMySql
- Springboot+Redisson自定義註解一次解決重複提交問題(含原始碼)Spring BootRedis原始碼
- 何為Redis單據鎖,你又是如何防止併發重複寫入的Redis
- SpringMVC後臺token防重複提交解決方案SpringMVC
- WEB安全新玩法 [8] 阻止訂單重複提交Web
- 對於防止按鈕重複點選的嘗試
- 分散式重複提交問題架構設計思路分散式架構
- SpringBoot自定義註解+AOP+redis實現防介面冪等性重複提交,從概念到實戰Spring BootRedis
- vue帶參請求,登入時效(防止重複登陸)Vue
- 如何利用限流解決遊戲陪玩app開發中的重複提交問題?遊戲APP
- 防止點選enter回車提交表單
- #每日一記#防止按鈕在短時間內重複點選
- 【java工程師必知必會】spring防重複提交AOP方式Java工程師Spring
- 歷途人是如何防止避重就輕的
- 重複照片清理工具PhotoSweeper X ,如何清理重複圖片
- iOS UIButton之防止重複點選(控制事件響應時間間隔)iOSUI事件
- Laravel 是怎樣防止你的定時任務重複執行的Laravel