防重複提交解決方案!史上最全原理解析!

傳統方式(不推薦)

首先我們介紹下之前傳統的防重複提交方式:

1:前端處理:

思路如下:

function dosubmit(){

//第一步,我們需要獲取表單的提交按鈕。

var btnSubmit = document.getElementById("submit");

//第二步,需要將表單提交按鈕設置爲不可用(或則直接隱藏,但是隱藏的話會被認爲是BUG),這樣就可以避免用戶再次點擊提交按鈕,進行提交操作。

btnSubmit.disabled= "disabled";

//第三步,返回true讓表單可以正常提交。

return true;

}

2:服務端session處理

思路如下:

1、在服務器端生成一個唯一的隨機標識號,專業術語稱爲Token(令牌),並在當前用戶的Session域中保存這個Token。

2、將Token發送到客戶端的Form表單中,在Form表單中使用隱藏域來存儲這個Token,表單提交的時候連同這個Token一起提交到服務器端。

3、在服務器端判斷客戶端提交上來的Token與服務器端生成的Token是否一致,如果不一致,那就是重複提交了,此時服務器端就可以不處理重複提交的表單。如果相同則處理表單提交,處理完後清除當前用戶的Session域中存儲的標識號。

Spring-AOP防重解決方案(推薦)

以上是比較早的防重複提交解決方案,本文我們再介紹一種:

服務端Spring -AOP防重

思路如下:

1、自定義註解 @NoRepeatSubmit 標記有必要防重複提交請求Controller。

2、通過Spring-AOP方式對所有標記了 @NoRepeatSubmit 的方法進行切入攔截。

3、在業務方法執行前,獲取當前用戶的 token+ 當前請求地址,作爲一個唯一 KEY,去獲取 Redis 分佈式鎖(如果此時併發獲取,只有一個線程會被成功獲取到鎖)。

4、業務方法執行後,一定要釋放鎖,異常也要釋放鎖(放到finally中釋放亦可)。

通過上面測試,我們看到初始化十個線程,只有一個線程是提交成功了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章