防止表單重復(fù)提交

通過JavaScript屏蔽(不推薦)

???????????????????????????????????????寫標(biāo)記falg? (return false擅这;)

兩種方式

??????????????????????????????????????禁用按鈕disabled(添加disable的屬性)

弊端:js代碼很容易被繞過厢洞。比如通過刷新頁面方式,或使用postman等工具繞過前段頁面仍能重復(fù)提交表單绩郎。因此不推薦此方法蔼水。


給數(shù)據(jù)庫增加唯一鍵約束(簡單粗暴)

在數(shù)據(jù)庫建表的時(shí)候在ID字段添加主鍵約束赖瞒。

用戶名女揭、郵箱、電話等字段加唯一性約束栏饮。確保數(shù)據(jù)庫只可以添加一條數(shù)據(jù)吧兔。

數(shù)據(jù)庫加唯一性約束sql:

alter table tableName_xxx add unique key uniq_xxx(field1, field2)

服務(wù)器及時(shí)捕捉插入數(shù)據(jù)異常:

??????? try {

???????????????xxxMapper.insert(user);

??????????? } catch(DuplicateKeyException e) {

???????????????logger.error("user already exist");

??????????? }

弊端:無法阻止惡意用戶重復(fù)提交表單(攻擊網(wǎng)站),服務(wù)器大量執(zhí)行sql插入語句袍嬉,增加服務(wù)器和數(shù)據(jù)庫負(fù)荷境蔼。


添加函數(shù)防抖

詳見函數(shù)去抖、節(jié)流

利用Session防止表單重復(fù)提交(推薦)

服務(wù)器返回表單頁面時(shí)伺通,會先生成一個(gè)subToken保存于session箍土,并把該subToen傳給表單頁面。

當(dāng)表單提交時(shí)會帶上subToken罐监,服務(wù)器攔截器Interceptor會攔截該請求吴藻,攔截器判斷session保存的subToken和表單提交subToken是否一致。若不一致或session的subToken為空或表單未攜帶subToken則不通過笑诅。

首次提交表單時(shí)session的subToken與表單攜帶的subToken一致走正常流程调缨,

然后攔截器內(nèi)會刪除session保存的subToken。

當(dāng)再次提交表單時(shí)由于session的subToken為空則不通過吆你。從而實(shí)現(xiàn)了防止表單重復(fù)提交。

使用:

mvc配置文件加入攔截器配置

<mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><bean class="xxx.xxx.interceptor.AvoidDuplicateSubmissionInterceptor"/></mvc:interceptor></mvc:interceptors>

攔截器

package xxx.xxxx.interceptor;

importxxx.xxx.SubToken;

importorg.apache.struts.util.TokenProcessor;

importorg.springframework.web.method.HandlerMethod;

importorg.springframework.web.servlet.handler.HandlerInterceptorAdapter;

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

import java.lang.reflect.Method;

public class AvoidDuplicateSubmissionInterceptor extends


HandlerInterceptorAdapter {

public AvoidDuplicateSubmissionInterceptor() {

??? }

@Override


public boolean preHandle(HttpServletRequestrequest,

????????????????????????????HttpServletResponse response, Object handler)

throwsException {


if (handler instanceofHandlerMethod) {

??????????? HandlerMethod handlerMethod= (HandlerMethod) handler;

??????????? Method method =handlerMethod.getMethod();

???????????SubToken annotation = method

???????????????????.getAnnotation(SubToken.class);


if (annotation != null){


booleanneedSaveSession = annotation.saveToken();


if(needSaveSession) {


?request.getSession(false)

???????????????????????????.setAttribute

(


"subToken",

???????????????????????????????????TokenProcessor.getInstance().generateToken(

???????????????????????????????????????????request));

??????????????? }

booleanneedRemoveSession = annotation.removeToken();


if(needRemoveSession) {


if(isRepeatSubmit(request)) {


return false;

??????????????????? }

??????????????????? request.getSession(

false).removeAttribute("subToken");

??????????????? }

??????????? }

??????? }


return true;

??? }

private boolean isRepeatSubmit(HttpServletRequest request){

??????? String serverToken = (String)

request.getSession(false).getAttribute(


"subToken");


if (serverToken == null){


return true;

??????? }

??????? String clinetToken =request.getParameter(

"subToken");


if (clinetToken == null){


return true;

??????? }


if(!serverToken.equals(clinetToken)) {


return true;

??????? }


return false;

??? }

}?

控制層 controller

@RequestMapping("/form")

//開啟一個(gè)Token@SubToken(saveToken

= true)

publicString form() {


return "/test/form";

}

@RequestMapping(value = "/postForm", method = RequestMethod.POST)

@ResponseBody//開啟Token驗(yàn)證俊犯,并且成功之后移除當(dāng)前Token@SubToken(removeToken = true)

public String postForm(String userName) {

?System.out.println(System.currentTimeMillis());


try{

???System.out.println(userName);

??? Thread.sleep(1500);

//暫停1.5秒后程序繼續(xù)執(zhí)行

? }

catch(InterruptedException e) {

??? e.printStackTrace();

?}

?System.out.println(System.currentTimeMillis());


return "1";

}

表單頁面

<%@ page contentType="text/html;charset=UTF-8"language="java" %><html><head><title>Title</title></head><body><form method="post"action="/postForm"><input type="text" name="userName"><inputtype="hidden"

name="subToken" value="${subToken}"><inputtype="submit" value="提交"></form></body></html>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末妇多,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子燕侠,更是在濱河造成了極大的恐慌者祖,老刑警劉巖立莉,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異七问,居然都是意外死亡蜓耻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門械巡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刹淌,“玉大人,你說我怎么就攤上這事讥耗∮泄矗” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵古程,是天一觀的道長蔼卡。 經(jīng)常有香客問我,道長挣磨,這世上最難降的妖魔是什么雇逞? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮茁裙,結(jié)果婚禮上塘砸,老公的妹妹穿的比我還像新娘。我一直安慰自己呜达,他們只是感情好谣蠢,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著查近,像睡著了一般眉踱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上霜威,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天谈喳,我揣著相機(jī)與錄音,去河邊找鬼戈泼。 笑死婿禽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的大猛。 我是一名探鬼主播扭倾,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼挽绩!你這毒婦竟也來了膛壹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎模聋,沒想到半個(gè)月后肩民,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡链方,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年持痰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祟蚀。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡工窍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出暂题,到底是詐尸還是另有隱情移剪,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布薪者,位于F島的核電站纵苛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏言津。R本人自食惡果不足惜攻人,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悬槽。 院中可真熱鬧怀吻,春花似錦、人聲如沸初婆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽磅叛。三九已至屑咳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弊琴,已是汗流浹背兆龙。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留敲董,地道東北人紫皇。 一個(gè)月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像腋寨,于是被迫代替她去往敵國和親聪铺。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容