Web應(yīng)用中重復(fù)提交的問題的三種解決方案
前兩種是利用javascript,后面一種是在使用Struts的情況下的參考實(shí)現(xiàn):
1、javascript ,設(shè)置一個(gè)變量,只允許提交一次。
<script language="javascript">
var checkSubmitFlg = false;
function checkSubmit()
{
if (checkSubmitFlg == true)
{
return false;
}
checkSubmitFlg = true;
return true;
}
document.ondblclick =
function docondblclick()
{
window.event.returnValue = false;
}
document.onclick =
function doconclick()
{
if (checkSubmitFlg)
{
window.event.returnValue = false;
}
}
</script>
<html:form action="myAction.do"
method="post" onsubmit="return checkSubmit();"> |
2、還是javascript,將提交按鈕或者image置為disable
<html:form action="myAction.do"
method="post"
onsubmit="getElById('submitInput')
.disabled = true;
return true;
">
<html:image
styleId="submitInput"
src="images/ok_b.gif"
border="0" />
</html:form> |
3、利用struts的同步令牌機(jī)制
利用同步令牌(Token)機(jī)制來解決Web應(yīng)用中重復(fù)提交的問題,Struts也給出了一個(gè)參考實(shí)現(xiàn)。
基本原理:
服務(wù)器端在處理到達(dá)的請(qǐng)求之前,會(huì)將請(qǐng)求中包含的令牌值與保存在當(dāng)前用戶會(huì)話中的令牌值進(jìn)行比較,
看是否匹配。在處理完該請(qǐng)求后,且在答復(fù)發(fā)送給客戶端之前,將會(huì)產(chǎn)生一個(gè)新的令牌,該令牌除傳給
客戶端以外,也會(huì)將用戶會(huì)話中保存的舊的令牌進(jìn)行替換。這樣如果用戶回退到剛才的提交頁面并再次
提交的話,客戶端傳過來的令牌就和服務(wù)器端的令牌不一致,從而有效地防止了重復(fù)提交的發(fā)生。
if (isTokenValid(request, true))
{
// your code here
return mapping.findForward("success");
} else
{
saveToken(request);
return mapping.findForward
("submitagain");
} |
Struts根據(jù)用戶會(huì)話ID和當(dāng)前系統(tǒng)時(shí)間來生成一個(gè)唯一(對(duì)于每個(gè)會(huì)話)令牌的,具體實(shí)現(xiàn)可以參考TokenProcessor類中的generateToken()方法。
1. //驗(yàn)證事務(wù)控制令牌,
會(huì)自動(dòng)根據(jù)session中標(biāo)識(shí)生成一個(gè)隱含input代表令牌,防止兩次提交
2. 在action中:
//<input type="hidden"
name="org.apache.struts.taglib.html.TOKEN"
// value="6aa35341f25184fd996c4c918255c3ae">
if (!isTokenValid(request))
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("error.transaction.token"));
resetToken(request);
//刪除session中的令牌 |
3. action有這樣的一個(gè)方法生成令牌
protected String generateToken
(HttpServletRequest request)
{
HttpSession session =
request.getSession();
try
{
byte id[] =
session.getId().getBytes();
byte now[] =
new Long(System.currentTimeMillis()).
toString().getBytes();
MessageDigest md =
MessageDigest.getInstance("MD5");
md.update(id);
md.update(now);
return (toHex(md.digest()));
} catch (IllegalStateException e)
{
return (null);
} catch (NoSuchAlgorithmException e)
{
return (null);
}
} |
posted on 2006-04-19 11:06
我心依舊 閱讀(634)
評(píng)論(0) 編輯 收藏