解決表單重復(fù)提交

解決方案

使用javascript 解決

?既然存在上述所說(shuō)的表單重復(fù)提交問(wèn)題,那么我們就要想辦法解決障斋,比較常用的方法是采用JavaScript來(lái)防止表單重復(fù)提交纵潦,具體做法如下:

修改form.jsp頁(yè)面当纱,添加如下的JavaScript代碼來(lái)防止表單重復(fù)提交

代碼:

<%@pagelanguage="java"contentType="text/html; charset=UTF-8"

??? pageEncoding="UTF-8"%>

DOCTYPEhtmlPUBLIC"-//W3C//DTD

? HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<title>Form表單title>

<scripttype="text/javascript">

??? var isFlag = false;?//表單是否已經(jīng)提交標(biāo)識(shí)靶衍,默認(rèn)為false

?

??? function submitFlag() {

?

??????? if (!isFlag) {

??????????? isFlag =true;

??????????? return?true;

??????? }else {

??????????? return?false;

??????? }

?

??? }

script>

head>

?

<body>

??? <formaction="${pageContext.request.contextPath}/DoFormServlet"

??????? method="post"onsubmit="return submitFlag()">

??????? 用戶(hù)名:<inputtype="text"name="userName">?"submit"

??????????? value="提交"id="submit">

??? form>

body>

html>

?除了用這種方式之外,經(jīng)常見(jiàn)的另一種方式就是表單提交之后椅挣,將提交按鈕設(shè)置為不可用遂庄,讓用戶(hù)沒(méi)有機(jī)會(huì)點(diǎn)擊第二次提交按鈕寥院,代碼如下:


function dosubmit(){


? //獲取表單提交按鈕


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


? //將表單提交按鈕設(shè)置為不可用,這樣就可以避免用戶(hù)再次點(diǎn)擊提交按鈕


? btnSubmit.disabled= "disabled";


? //返回true讓表單可以正常提交


? return true;

}



使用后端提交解決

?對(duì)于【場(chǎng)景二】和【場(chǎng)景三】導(dǎo)致表單重復(fù)提交的問(wèn)題涛目,既然客戶(hù)端無(wú)法解決秸谢,那么就在服務(wù)器端解決凛澎,在服務(wù)器端解決就需要用到session了。

? 具體的做法:在服務(wù)器端生成一個(gè)唯一的隨機(jī)標(biāo)識(shí)號(hào)估蹄,專(zhuān)業(yè)術(shù)語(yǔ)稱(chēng)為Token(令牌)塑煎,同時(shí)在當(dāng)前用戶(hù)的Session域中保存這個(gè)Token。然后將Token發(fā)送到客戶(hù)端的Form表單中元媚,在Form表單中使用隱藏域來(lái)存儲(chǔ)這個(gè)Token轧叽,表單提交的時(shí)候連同這個(gè)Token一起提交到服務(wù)器端,然后在服務(wù)器端判斷客戶(hù)端提交上來(lái)的Token與服務(wù)器端生成的Token是否一致刊棕,如果不一致炭晒,那就是重復(fù)提交了,此時(shí)服務(wù)器端就可以不處理重復(fù)提交的表單甥角。如果相同則處理表單提交网严,處理完后清除當(dāng)前用戶(hù)的Session域中存儲(chǔ)的標(biāo)識(shí)號(hào)。? 在下列情況下嗤无,服務(wù)器程序?qū)⒕芙^處理用戶(hù)提交的表單請(qǐng)求:

[if !supportLists]1.????????[endif]存儲(chǔ)Session域中的Token(令牌)與表單提交的Token(令牌)不同震束。

[if !supportLists]2.????????[endif]當(dāng)前用戶(hù)的Session中不存在Token(令牌)

[if !supportLists]3.????????[endif]用戶(hù)提交的表單數(shù)據(jù)中沒(méi)有Token(令牌)当犯。

轉(zhuǎn)發(fā)代碼:

@WebServlet("/ForwardServlet")

public?class?ForwardServlet?extends? HttpServlet {

???? @Override

???? protected?void doGet(HttpServletRequest

? req, HttpServletResponse resp) throws ServletException, IOException {

???????? req.getSession().setAttribute("sesionToken", TokenUtils.getToken());

???????? req.getRequestDispatcher("form.jsp").forward(req, resp);

???? }

}

轉(zhuǎn)發(fā)頁(yè)面:

<%@pagelanguage="java"contentType="text/html; charset=UTF-8"

????? pageEncoding="UTF-8"%>

DOCTYPEhtmlPUBLIC"-//W3C//DTD

? HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<title>Form表單title>

?

head>

?

<body>

????? <formaction="${pageContext.request.contextPath}/DoFormServlet"

?????????? method="post"onsubmit="return dosubmit()">

?????????? <inputtype="hidden"name="token"value="${sesionToken}"> 用戶(hù)名:<inputtype="text"

???????????????? name="userName">?"submit"value="提交"id="submit">

????? form>

body>

html>

后端Java代碼:

@WebServlet("/DoFormServlet")

public?class?DoFormServlet?extends HttpServlet {

???? @Override

???? protected?void? doPost(HttpServletRequest req,

? HttpServletResponse resp) throws ServletException, IOException {

???????? req.setCharacterEncoding("UTF-8");

???????? boolean?flag = isFlag(req);

???????? if (!flag) {

????????????? resp.getWriter().write("已經(jīng)提交...");

????????????? System.out.println("數(shù)據(jù)已經(jīng)提交了..");

????????????? return;

???????? }

???????? StringuserName = req.getParameter("userName");

???????? try {

????????????? Thread.sleep(300);

???????? }catch (Exception e) {

????????????? // TODO: handle exception

???????? }

???????? System.out.println("往數(shù)據(jù)庫(kù)插入數(shù)據(jù)...." + userName);

???????? resp.getWriter().write("success");

???? }


???? public?boolean? isFlag(HttpServletRequest request) {

???????? HttpSessionsession = request.getSession();

???????? StringsesionToken = (String) session.getAttribute("sesionToken");

???????? Stringtoken = request.getParameter("token");

???????? if (!(token.equals(sesionToken))) {

????????????? return?false;

???????? }

???????? session.removeAttribute("sesionToken");

???????? return?true;

???? }

}




Filter 也稱(chēng)之為過(guò)濾器垢村,它是 Servlet 技術(shù)中最實(shí)用的技術(shù),Web 開(kāi)發(fā)人員通過(guò) Filter 技術(shù)嚎卫,對(duì) web 服務(wù)器管理的所有 web 資源:例如 Jsp,

Servlet, 靜態(tài)圖片文件或靜態(tài) html文件等進(jìn)行攔截嘉栓,從而實(shí)現(xiàn)一些特殊的功能。例如實(shí)現(xiàn) URL級(jí)別的權(quán)限訪問(wèn)控制拓诸、過(guò)濾敏感詞匯侵佃、壓縮響應(yīng)信息等一些高級(jí)功能。

它主要用于對(duì)用戶(hù)請(qǐng)求進(jìn)行預(yù)處理奠支,也可以對(duì)HttpServletResponse 進(jìn)行后處理馋辈。使用 Filter的完整流程:Filter 對(duì)用戶(hù)請(qǐng)求進(jìn)行預(yù)處理,接著將請(qǐng)求交給 Servlet 進(jìn)行處理并生成響應(yīng)倍谜,最后 Filter 再對(duì)服務(wù)器響應(yīng)進(jìn)行后處理迈螟。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市尔崔,隨后出現(xiàn)的幾起案子井联,更是在濱河造成了極大的恐慌,老刑警劉巖您旁,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異轴捎,居然都是意外死亡鹤盒,警方通過(guò)查閱死者的電腦和手機(jī)蚕脏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)侦锯,“玉大人驼鞭,你說(shuō)我怎么就攤上這事〕吲觯” “怎么了挣棕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)亲桥。 經(jīng)常有香客問(wèn)我洛心,道長(zhǎng),這世上最難降的妖魔是什么题篷? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任词身,我火速辦了婚禮,結(jié)果婚禮上番枚,老公的妹妹穿的比我還像新娘法严。我一直安慰自己,他們只是感情好葫笼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布深啤。 她就那樣靜靜地躺著,像睡著了一般路星。 火紅的嫁衣襯著肌膚如雪溯街。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天奥额,我揣著相機(jī)與錄音苫幢,去河邊找鬼。 笑死垫挨,一個(gè)胖子當(dāng)著我的面吹牛韩肝,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播九榔,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼哀峻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了哲泊?” 一聲冷哼從身側(cè)響起剩蟀,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎切威,沒(méi)想到半個(gè)月后育特,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年缰冤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了犬缨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡棉浸,死狀恐怖怀薛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情迷郑,我是刑警寧澤枝恋,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站嗡害,受9級(jí)特大地震影響焚碌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜就漾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一呐能、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抑堡,春花似錦摆出、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至有缆,卻和暖如春象踊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棚壁。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工杯矩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人袖外。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓史隆,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親曼验。 傳聞我的和親對(duì)象是個(gè)殘疾皇子泌射,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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