使用验证码处理表单重复提交的问题

本文探讨了表单重复提交的三种常见情况,如请求转发、网络延迟及浏览器回退,并介绍了如何通过谷歌验证码和前端验证机制来解决。重点讲解了在web.xml中配置KaptchaServlet和验证过程的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、表单重复提交

表单重复提交第一种情况:

提交完表单,服务器使用请求转来进行页面跳转。这个时候,用户按下功能键 F5,就会发起最后一次的请求,造成表单重复提交问题。这种情况可以使用重定向来进行跳转。

// 如果是请求转发的话,浏览器会保存最后一次请求,以及所有参数,刷新会继续提交表单项,
//使用重定向则是新的一次请求,重定向到list,相当于最后一次请求是list,所以即使刷新,还是在list页面
response.sendRedirect(request.getContextPath() + "/");

表单重复提交第二种情况:

用户正常提交服务器,但是由于网络延迟等原因,迟迟未收到服务器的响应,这个时候如果多点了几次提交操作,也会造成表单重复提交。

表单重复提交第三种情况:

用户正常提交服务器。服务器也没有延迟,但是提交完成后,用户回退浏览器,然后重新提交,这样也会造成表单重复提交。

二、验证码解决表单重复提交的底层原理

在这里插入图片描述
使用谷歌 kaptcha 图片验证码

web.xml 中去配置用于生成验证码的 Servlet 程序

    <servlet>
        <servlet-name>KaptchaServlet</servlet-name>
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>KaptchaServlet</servlet-name>
        <url-pattern>/kaptcha.jpg</url-pattern>
    </servlet-mapping>

在服务器获取谷歌生成的验证码和客户端发送过来的验证码比较使用

    protected void regist(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取Session中的验证码
        String token = (String) request.getSession().getAttribute(KAPTCHA_SESSION_KEY);
        //删除Session中的验证码
        request.getSession().removeAttribute(KAPTCHA_SESSION_KEY);



        //1.获取请求的参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String email = request.getParameter("email");
        String code = request.getParameter("code");


        User user = WebUtils.copyParamToBean(request.getParameterMap(), new User());

        //2.检查验证码是否正确
        if (token != null && token.equalsIgnoreCase(code)){

            //3.验证码正确,检查用户名是否可用
            if (userService.existUsername(username)){
                System.out.println("用户名[" + username + "]已存在!");
                //把回显信息保存到request域中
                request.setAttribute("msg","用户名已存在!");
                request.setAttribute("username",username);
                request.setAttribute("email",email);

                request.getRequestDispatcher("/pages/user/regist.jsp").forward(request,response);
            }else {
                userService.registerUser(user);
                request.getRequestDispatcher("/pages/user/regist_success.jsp").forward(request,response);
            }
        }else {
            //把回显信息保存到request域中
            request.setAttribute("msg","验证码错误!");
            request.setAttribute("username",username);
            request.setAttribute("email",email);

            //4.验证码不正确,跳回注册页面
            request.getRequestDispatcher("/pages/user/regist.jsp").forward(request,response);
        }
    }

还可以实现切换验证码

		//给验证码绑定切换图片的单击事件
	    $("#code_img").click(function () {
	        //在事件响应的function函数中有一个this对象,这个this对象就是当前正在响应事件的dom对象
			//这里的this就是验证码图片响应事件,所以this就表示<img/>这个标签
			//src属性表示验证码img标签的图片路径,src可读可写,赋值之后会重新发起一次请求
			//末尾加上时间戳是为了使得每次刷新验证码请求地址不一样,进而跳过浏览器缓存
			this.src = "${basePath}/kaptcha.jpg";
        });

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值