利用Session防止表单重复提交
重复提交的危害:
在投票的网页上不停地提交,实现了刷票的效果。
注册多个用户,不断发帖子,扰乱正常发帖秩序。
首先我们来看一下常见的重复提交:
在处理表单的Servlet中刷新。
后退再提交
网络延迟,多次点击提交按钮
于网络延迟造成的多次提交数据给服务器,其实是客户端的问题。于是,我们可以使用javaScript来防止这种情况。要做的事情也非常简单:当用户第一次点击提交按钮时,把数据提交给服务器。当用户再次点击提交按钮时,就不把数据提交给服务器了。
监听用户提交事件。只能让用户提交一次表单!
在处理表单的Servlet中刷新和后退再提交这两种方式javaScript代码无法阻止这两种情况的发生。
得用其他办法来阻止表单数据重复提交了。我们现在学了Session,Session可以用来标识一个用户是否登陆了。Session的原理也说了:不同的用户浏览器会拥有不同的Session。而request和ServletContext为什么就不行呢?
request的域对象只能是一次http请求,提交表单数据的时候request域对象的数据取不出来。ServletContext代表整个web应用,如果有几个用户浏览器同时访问,ServletContext域对象的数据会被多次覆盖掉,也就是说域对象的数据就毫无意义了。
可能到这里,我们会想到:在提交数据的时候,存进Session域对象的数据,在处理提交数据的Servlet中判断Session域对象数据?。究竟判断Session什么?判断Session域对象的数据不为null?没用呀,既然已经提交过来了,那肯定不为null。
此时,我们就想到了,在表单中还有一个隐藏域,可以通过隐藏域把数据交给服务器。
判断Session域对象的数据和jsp隐藏域提交的数据是否对应。
判断隐藏域的数据是否为空【如果为空,就是直接访问表单处理页面的Servlet】
判断Session的数据是否为空【servlet判断完是否重复提交,最好能立马移除Session的数据,不然还没有移除的时候,客户端那边儿的请求又来了,就又能匹配了,产生了重复提交。如果Session域对象数据为空,证明已经提交过数据了!】
我们向Session域对象的存入数据究竟是什么呢?简单的一个数字?好像也行啊。因为只要Session域对象的数据和jsp隐藏域带过去的数据对得上号就行了呀,反正在Servlet上判断完是否重复提交,会立马把Session的数据移除掉的。更专业的做法是:向Session域对象存入的数据是一个随机数【Token--令牌】。
生成一个唯一的随机数,并跳转到login.jsp页面
随机数生成类
jsp隐藏域获取到Session的值
在处理表单提交页面中判断:jsp隐藏域是否有值带过来,Session中的值是否为空,Session中的值和jsp隐藏域带过来的值是否相等。
实现原理是非常简单的:
a、在session域中存储一个token。
b、然后前台页面的隐藏域获取得到这个token。
c、在第一次访问的时候,我们就判断seesion有没有值,如果有就比对。对比正确后我们就处理请求,接着就 把session存储的数据给删除了。
d、等到再次访问的时候,我们session就没有值了,就不受理前台的请求了。
领取专属 10元无门槛券
私享最新 技术干货