javaweb解决表单重复提交问题
一、表单重复提交的三种情况:
1.提交完表单。服务器使用请求转来进行页面跳转。这个时候,用户按下功能键F5,就会发起最后一次请求。造成表单重复提交问题。解决方法:使用重定向来进行跳转。
因为重定向其实就是发生了一次服务器请求。
2.用户正常提交服务器,但是由于网络延迟等原因,迟迟未收到服务器的响应,这个时候,用户以为提交失败,就会着急,然后多点了几次提交按钮,也会造成表单重复提交。
3.用户正常提交服务器,服务器也没有延迟,但是提交完成后,用户回退浏览器,重新提交。也会造成表单的重复提交。
二、解决方法:
第一个问题,我们由上可知使用重定向的方式来来跳转页面代替最后一次服务器的请求。后两种情况,我们使用验证码的方式来解决。
1.验证码的原理
- 当用户第一次访问表单的时候,就要给表单生成一个验证码字符串
- 把生成的验证码字符串保存在session域中
- 要把验证码生成为验证码图片显示 在表单中
- 比较Session中的验证码和表单项中的验证码是否相等。比较完之后,删除Session中的验证码。
- 此时Session中没有验证码,当用户重复提交的时候,由于验证码还是上一次的内容,所以此时比较为不等,从而阻止了重复提交。
2.谷歌验证码的使用
谷歌验证码kaoatcha使用步骤如下:
- 导入谷歌验证码的jar包:
jar包以及有关使用都在链接: 点击获取. - 在web.xml中配置用于生成验证码的Servelt程序。
<servlet>
<servlet-name>Kaptcha</servlet-name>
//jar包中KaptchaServlet类的地址
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Kaptcha</servlet-name>
//名称是自定义的
<url-pattern>/kaptcha.jpg</url-pattern>
</servlet-mapping>
- 在表单中使用img标签去显示验证码图片并使用它
<form action="" method="get">
用户名:<input type="text" name="username">
验证码:<input type="text" name="code">
<img src="http://localhost:8080/book/kaptcha.jpg" style="">
<input type="submit" value="登录">
</form>
- 在服务器获取谷歌生成的验证码和客户端发送过来的验证码。
//获取Session中的验证码
String token=request.getSession().getAttribute("KAPTCHA_SEESSION_KEY");
//删除Session中的验证码
request.getSession().removeAttribute("KAPTCHA_SESSION_KEY");
//获取客户端的验证码
String code=request.getParameter("code");
//判断验证码是否匹配,以及验证码是否存在
if(token!=null&&token.equalsIgnoreCase(code)){
Sysetem.out.println("成功提交!");
}
3.验证码的刷新
有时候验证码的图案会看不清的情况,这时候可以通过点击刷新验证码得到新的验证码图片。
方法:在前端页面绑定单击事件,使用js实现刷新功能。
$(function(){
$("#code_img").click(function(){
//在事件响应的function函数中有一个this对象,这个this对象就是当前正在响应的dom对象
//src属性表示验证码img标签的图片路径。可读可写
this.src="${basePath}kaptcha.jpg";
});
});
通过上面的方法就可以实现验证码图片的刷新。但是在火狐浏览器中就会翻车。原因如下:
- 浏览器为了让请求速度更快。就会把每次请求的内容缓存到了浏览器端(要么硬盘上,要么内存中)。http://localhost:8080/book/kaptcha.jpg.
- 所以点击后就会根据上面的地址访问一次服务器,服务器返回生成的验证码图片。由于在缓存中保存着这样的地址,所以访问的时候会从缓存中内容。所以再次请求的时候,验证码图片和上次的一样。
解决方法:
即跳过浏览器的请求,而发起请求给服务器获取新验证码。给每次请求的地址后面加上不同的参数,从而实现每次请求的地址都不一样。
//在刷新验证码的点击事件中 加一个时间戳 而这个事件每次都是不同的。
this.src="${basePath}kaptcha.jpg?d="+new Date();