在日常生活中,网速不好的时候,经常出现提交表单后网页没有跳转或一直在跳转中,这时可能急性子的用户就会不停地按提交按钮,导致重复提交。重复提交会加重服务器压力。今天我们就来讨论下怎么防止重复提交
一.前台防止重复提交
<form action="about:blank" method="post" onsubmit ="getElementById('submitInput').disabled=true;return true;" target="_blank">
<input type="submit" value="提交" id="submitInput" onclick="this.value='提交ing···';"/>
</form>
通过onsubmit方法使表单提交后按钮变为disabled,通过按钮添加onClick事件使按钮文字变为“提交ing···”,表示正在提交中。
效果:
提交前:
提交后:
尽管这样,但用户有时会耐不住性子刷新页面或者按后退重新提交,又或者浏览器禁止javascript,那就要用后台来防止重复提交了。
二.后台防止重复提交
<form method="post" action="handler" name="theForm">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td>
<input type="password" name="password">
<input type="hidden" name="org.sunxin.token" value="<%=token%>"/>
</td>
</tr>
<tr>
<td><input type="reset" value="重填"></td>
<td><input type="button" name="btnSubmit" value="提交" onClick="checkSubmit();"/></td>
</tr>
先写个表单,如上图,用隐藏表单记录token属性(注意隐藏域中的名字必须与下面令牌类定义的静态变量TOKEN_KEY一致)。当提交表单后,HandlerServlet程序会比较隐藏域中的值和Session域中的标志号,如果相同就处理表单数据,处理后就清除当前用户Session域中存储的标识符,如果不相同就会忽略表单请求。当重复提交表单时,当前Session域中会不存在相应的表单标识号。接下来要写一个名为TokenProcessor的令牌类:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* TokenProcessor类是一个单例类。
*/
public class TokenProcessor
{
static final String TOKEN_KE