曾多次听人提起过“限制表单重复”, 但是那时不明白是怎么一回事, 今天就学习了一把。以下是学习笔记:
首先谈谈自己的感受: 以前在运行web项目过曾中时而碰到503错误(也即当前的请求无效), 那时我一直都没有觉得什么不妥, ^_^ ^_^ 因为稍微等一下再运行就可以了。 对于自己平时在编写项目的过程中是没什么问题, 但是对于一个上线的项目来说这种情况则是不允许出现的。
在提交表单的时候如何保护正常的控制流程(业务逻辑)不被破坏。 例如当一个客户在填写或修改完数据提交表单后, 由于响应太慢或其他一些原因, 客户可能会在服务器相应这个处理之前多次单击提交按钮; 或当服务器已经完成处理以后, 客户通过浏览器的后退按钮又返回到以前的编辑修改页面, 再次单击提交按钮, 这些情况都会破坏程序的正常的控制流程(业务逻辑), 所以必须在设计和编程中加以控制和保护, 特别是在表单提交在服务器端包含事物处理的时候, 限制表单重复提交的错误就显得尤为重要!
——————————————————限制表单重复提交的思路————————————————————
如何限制表单重复提交? 目前在实际应用中存在两种解决方案, 分别是在客户端调用脚本或者直接在服务器端编程来实现。
a、 客户端解决方案:
对于一些简单的应用来说, 可以采用一个比较简单的方法来处理, 当用户提交后弹出一个页面, 提醒用户在提交后耐心等待服务器端相应而不要多次提交按钮。 但是这种方式风险很大,因为有些用户就是要多按乱按, ^_^ ^_^ 对于有经验的web设计人员来说可以采用一种更有效、同时也比较复杂的解决方法, 这种方法就是用户在第一次提交的时候设置一个标志, 通过这个标志变量就可以决定是否允许用户在什么情况下提交按钮。 不过这种方法也有缺点, 即或多或少依赖于所用的浏览器, 稳定性不是很好。 此外, 还可以考虑在单击提交按钮以后将提交按钮设置为disabled状态, 这样用户就无法再单击提交按钮, 客户端也就无法重复提交。
b、 服务器端解决方案:
在服务器端判断表单是否重复提交, 主要可以考虑在页面之间通过Session共享变量的方法来实现, 即咋客户端页面中设置session中的标志变量,然后在服务器端对Session中的标志变量进行判断。 此外, 在struts中还可以考虑采用令牌极致来判断表单是否重复提交。
————————————————————下面是我的试验代码————————————————————————
<script type="text/javascript">
//定义重复提交标志变量
var repeatSubmit = false;
function checkSubmit(){
if(repeatSubmit){
window.alert('禁止重复提交');
return false;
}
else{
repeatSubmit = true;
return true;
}
}
</script>
<form action="http://baidu.com" name="myform" onsubmit="return checkSubmit()">
平克.弗洛伊德————世上最伟大的摇滚乐队!
<input type="submit" value="提交" name="submit"/>
</form>
——————设置提交按钮限制客户端重复提交————————————
<form action="http://baidu.com" name="myform" onsubmit="window.document.myform.submit.disabled=true; return true;"/>
——————在服务器判断表单是否重复提交——————
在a.jsp页面中有如下:
session.putValue("submitFlag","a.jsp");
在接收页面b.jsp中进行判断:
String pageFlag;
pageFlag = (String) session.getValue("submitFlag");
if(pageFlag=="over"){ out.println("重复提交表单");}
else{ session.putValue("submitFlag","over");}
————————————————————-总结————————————————————————
技术难点主要在于如何发现表单已经提交, 对表单提交状态做出判断?
而通过session共享标志变量来判断是一个很好的方法。