当前位置: 首页 > news >正文

表单重复提交:

1. 表单重复提交原因

  • 当用户提交完请求,浏览器会记录最后一次请求的全部信息。用户按下功能键F5,就会发起浏览器记录的最后一次请求。如果最后一次请求为添加操作,那么此时刷新按钮就会再次提交数据,造成表单重复提交。

2. 表单重复提交的三种常见情况

  1. 提交完表单。服务器使用请求转来进行页面跳转。这个时候,用户按下功能键F5,就会发起最后一次的请求。造成表单重复提交问题。解决方法:使用重定向来进行跳转
  2. 用户正常提交服务器,但是由于网络延迟等原因,迟迟未收到服务器的响应,这个时候,用户以为提交失败,就会着急,然后多点了几次提交操作,也会造成表单重复提交。解决方法:使用验证码
  3. 用户正常提交服务器。服务器也没有延迟,但是提交完成后,用户回退浏览器。重新提交。也会造成表单重复提交。解决方法:使用验证码

3. 验证码原理

  • 用户第一次通过浏览器访问服务器的表单页面时候,会生成一个随机的验证码并保存在session中,之后为验证码生成一个验证码图片回显在表单页面中
  • 用户在访问到的页面中输入用户信息和验证码并发起请求,在后端程序中先回去session中的验证码并删除Session中的验证码(因为验证码只用一次),之后获取表单项信息,在比较表单项的验证码和获取到的Session验证码是否一致。如果相同则允许操作,不相等则阻止操作。
    • 第一次发起请求,表单项的验证码和获取到的Session验证码相等都为abcde,所以允许登录
    • 再次发起一个新的请求,由于Session的验证码已经删除了为null,表单项的验证码还为abcde,不相等所以不允许登录。

在这里插入图片描述

4. 谷歌验证码的使用步骤

说明

  • 验证码这种需求是很常见的业务,所以一般也不需要自己写代码,可以使用第三方封装好的验证码,比如:谷歌kaptcha图片验证码。
  • 以下步骤是在学习javaWeb时候的步骤,真正项目中使用的是SpringBoot整合后的步骤。

谷歌验证码 kaptcha 使用步骤如下:

  1. 导入谷歌验证码的 jar 包
    kaptcha-2.3.2.jar
  2. 在 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>
  1. 在表单中使用 img 标签去显示验证码图片并使用它
<form action="http://localhost:8080/tmp/registServlet" method="get">用户名:<input type="text" name="username" > <br>验证码:<input type="text" style="width: 80px;" name="code"><img src="http://localhost:8080/tmp/kaptcha.jpg" alt="" style="width: 100px; height: 28px;"> <br><input type="submit" value="登录">
</form>
  1. 在服务器获取谷歌生成的验证码和客户端发送过来的验证码比较使用。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException {// 获取 Session 中的验证码String token = (String) req.getSession().getAttribute(KAPTCHA_SESSION_KEY);// 删除 Session 中的验证码req.getSession().removeAttribute(KAPTCHA_SESSION_KEY);String code = req.getParameter("code");// 获取用户名String username = req.getParameter("username");if (token != null && token.equalsIgnoreCase(code)) {System.out.println("保存到数据库:" + username);resp.sendRedirect(req.getContextPath() + "/ok.jsp");} else {System.out.println("请不要重复提交表单");}
}
  1. 切换验证码:
// 给验证码的图片,绑定单击事件
$("#code_img").click(function () {// 在事件响应的 function 函数中有一个 this 对象。这个 this 对象,是当前正在响应事件的 dom 对象// src 属性表示验证码 img 标签的 图片路径。它可读,可写// alert(this.src);this.src = "${basePath}kaptcha.jpg?d=" + new Date();
});
http://www.lryc.cn/news/89611.html

相关文章:

  • 【0197】共享内存管理结构(shmem)之创建共享内存分配机制(Shared Memory Allocation)(2 - 2)
  • ChatGPT国内免费使用方法有哪些?
  • 【CloudCompare教程】012:基于点云数据的测量功能
  • 一体化医学影像平台PACS源码,影像存档与传输系统源码
  • 一篇文章打好SQL基础,熟悉数据库的基础操作和方法,以及安装MySQL软件包和Python操作MySQL基础使用
  • C4D R26 渲染学习笔记 建模篇(3):生成器
  • 智慧梁场3D建模
  • 《程序员面试金典(第6版)》面试题 02.08. 环路检测(哈希法,双指针,检测链表是否有环)
  • 软考A计划-试题模拟含答案解析-卷六
  • Linux 上的 .NET 崩溃了怎么抓 Dump
  • QT桌面项目(状态栏和导航栏设置)
  • 数据链路层:点对点协议PPP
  • C/C++读取txt文件中的float数据并用指针存储
  • 对KMP算法的一点碎碎念——上篇
  • 算法---边界着色
  • 二叉排序树的查找、插入、删除
  • 《Opencv3编程入门》学习笔记—第三章
  • 如何从Ubuntu Linux中删除Firefox Snap?
  • 数学建模的初阶-快速上手
  • 复习向 C/C++ 编程语言简介和概括(C++复习向p1)
  • DRF之过滤,排序,分页
  • 我的Redis学习,共写了14篇博客文章
  • mPython软件使用指南
  • 龙芯2K1000实战开发-系统配置详解
  • 【一起撸个DL框架】5 实现:自适应线性单元
  • 开箱即用的工具函数库xijs更新指南(v1.2.6)
  • 【Netty】ChannelPipeline源码分析(五)
  • 并行计算技术解密:MPI和OpenMP的学习和应用指南
  • 什么是自动化测试框架?我们该如何搭建自动化测试框架?
  • Debezium报错处理系列之六十七:TopicAuthorizationException: Not authorized to access topics