首页 > 其他分享 >防止form表单重复提交的几种方案

防止form表单重复提交的几种方案

时间:2024-04-16 11:24:07浏览次数:23  
标签:form 重复 用户 表单 提交 按钮 页面

form重复提交场景

  • 场景1:在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交。
    具体行为:在网络比较慢的情况下,用户连续快速的点击多次提交按钮。
  • 场景2:表单提交后用户点击【刷新】按钮导致表单重复提交。
    具体行为:用户点击了提交按钮,然后点击浏览器上的【刷新】按钮对form表单又进行一次提交。
  • 场景3:用户提交表单后,点击浏览器的【后退】按钮回退到表单页面后进行再次提交。

解决方案

防止用户重复提交主要有如下几种解决方案:

一:前端利用JavaScript防止表单重复提交

这种方法是使用户第二次点击提交按钮时是不起作用的。
该方案尚且可以应对用户通过前端正常访问网页时,重复提交的问题, 但是对于稍微懂点html知识的人来说,他可以打开控制台修改属性,该方案在非正常访问的时候,就会失效。

在客户端的js代码中设置一个标识位,第一次提交后将标志位设置成true。js代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
  <!DOCTYPE HTML>
  <html>
    <head>
      <title>Form表单</title>
          <script type="text/javascript">
          var isCommitted = false;//表单是否已经提交标识,默认为false
          function dosubmit(){
              if(isCommitted==false){
                 isCommitted = true;//提交表单后,将表单是否已经提交标识设置为true
                 return true;//返回true让表单正常提交
             }else{
                 return false;//返回false那么表单将不提交
             }
         }
     </script>
   </head>
   
   <body>
       <form action="${pageContext.request.contextPath}/servlet/DoFormServlet" onsubmit="return dosubmit()" method="post">
         用户名:<input type="text" name="username">
         <input type="submit" value="提交" id="submit">
     </form>
   </body>
 </html>

除了用这种方式之外,经常见的另一种方式就是表单提交之后,将提交按钮设置为不可用,让用户没有机会点击第二次提交按钮,代码如下:

function dosubmit(){
     //获取表单提交按钮
     var btnSubmit = document.getElementById("submit");
     //将表单提交按钮设置为不可用,这样就可以避免用户再次点击提交按钮
     btnSubmit.disabled= "disabled";
     //返回true让表单可以正常提交
     return true;
 }

使用JavaScript防止表单重复提交的做法只对上述提交到导致表单重复提交的三种场景中的【场景1】有效,而对于【场景2】和【场景3】是没有用,依然无法解决表单重复提交问题。

 

二:利用Session防止表单重复提交

对于【场景二】和【场景三】导致表单重复提交的问题,既然客户端无法解决,那么就在服务器端解决,在服务器端解决就需要用到session了。

具体的做法:

  1. 获取用户填写用户名和密码的页面时向后台发送一次请求,这时后台会生成唯一的随机标识号,专业术语称为Token(令牌)。

  2. Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,表单提交的时候连同这个Token一起提交到服务器端。

  3. 服务器端判断客户端提交上来的Token与服务器端生成的Token是否一致,如果不一致,那就是重复提交了,此时服务器端就可以不处理重复提交的表单。如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。

<?php
  session_start();
  if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['token'])) {
    $token = $_POST['token'];
    if ($_SESSION['token'] === $token) {
      //处理表单数据
      //...
      unset($_SESSION['token']);
    } else {
      echo '表单已提交!';
    }
  } else {
    $token = md5(uniqid(rand(), true));
    $_SESSION['token'] = $token;
?>
  <form method="post">
    <input type="hidden" name="token" value="<?php echo $token; ?>" />
    <!--其他表单元素-->
    <button type="submit">提交</button>
  </form>
<?php } ?>

 

三:使用重定向

在提交表单之后,如果你还使用相同的URL,会导致表单被重复提交。为了避免这种情况,你可以使用重定向。这种技术涉及到一个中间页面,可以在表单提交后,将用户重定向到另一个页面,而不是原始的表单页面。

以下是一个使用重定向来防止重复提交表单的示例:

<?php
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    //处理表单数据
    //...
    header('Location: success.php');
    exit;
  }
?>

 

在这个例子中,我们在处理完表单数据之后,使用header函数将用户重定向到success.php页面。这个页面是一个在提交成功后显示的页面,它不包含任何表单,因此用户无法使用浏览器的“后退”按钮或重新加载页面来重复提交表单。

 

更多:http://www.shanhubei.com/archives/55262.html

标签:form,重复,用户,表单,提交,按钮,页面
From: https://www.cnblogs.com/shanhubei/p/18137709

相关文章

  • 界面组件DevExpress WinForms v23.2 - 数据展示、UI模板功能全新升级
    DevExpressWinForms拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForms能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任!DevExpressWinForms控件日前正式发布了v23.2,此版......
  • 如何让表单流程引擎提质增效?
    随着社会的进步和科技的发展,低代码技术平台在诸多行业中成为利用价值高的平台。对于解决信息孤岛、部门协作不给力、办公效率不高等缺点,低代码技术平台都可以为其架设出一道优质的桥梁,共同朝着高效率的流程化办公方向前进。表单流辰引擎是提质增效的理想软件平台,优势特点多、可视......
  • axios 重复提交
    const{default:axios}=require("axios")constqs=require('qs')functionregsoleKey(config){const{method,url,params,data}=config;return[method,url,qs.stringify(params),qs.stringify(data)].join('&')......
  • 论文解读(Polynormer)《Polynormer: Polynomial-Expressive Graph Transformer in Linea
    Note:[wechat:Y466551|可加勿骚扰,付费咨询]2024年4月14日17:13:41论文信息论文标题:Polynormer:Polynomial-ExpressiveGraphTransformerinLinearTime论文作者:论文来源:2024 aRxiv论文地址:download论文代码:download视屏讲解:click1-摘要图转换器(GTs)已经成为一种......
  • git 提交之前的检查
    要使用pre-commit钩子,你需要执行以下步骤:找到.git/hooks目录:在你的Git仓库中,找到.git/hooks目录。这个目录包含了所有的Git钩子脚本。创建pre-commit钩子文件:在.git/hooks目录下创建一个名为pre-commit的文件。你可以使用任何文本编辑器创建这个文件。编写pre......
  • XAML UI 框架横向对比(Avalonia/Uno Platform/.NET MAUI)
    XAML框架横向对比多年来,基于XAML的UI框架有了很大的发展。下面的图表很好地证明了这个观点。XAMLUI框架的三大巨头:AvaloniaUI、UnoPlatform和.NETMAUI都支持跨平台的应用。事实上,除了AvaloniaUI,对跨平台XAML的需求是它们发展的主要动力。如果微软早一点介入,在几......
  • ModuleNotFoundError: No module named 'formatter'
    在学习韦东山Linux下载BSP章节时 走到第四步的时候出现ModuleNotFoundError:Nomodulenamed'formatter'的错误查了资料发现是第一步的问题,原因在于对于ubantu22.04来说formatter已在python3.4+标记成废弃接口,就算你按照网上教程添加这个模块也无法解决。解决方法是第一步......
  • 本地升级idea后,不能向github上提交代码问题处理
    问题现象:本人自己电脑之前一直使用idea2018.1商业破解版,之前有简历本地代码仓库,并在github上建立了关联的远程代码仓库。最近本人在本地升级一下idea,从idea2018.1商业版升级到2023.1.5社区版本(idea支持win7的版本基本就到2023.1这个版本了,目前本人尝试安装了2023.1.5和2023.1.3......
  • Ant - Form 自定义组件 form.getFiledsValue 如何获取值
    import{FC,useState}from'react';importtype{SelectProps}from'antd';import{Select,Space,Flex,Input,Button}from'antd';/***扩展选择器组件,可以通过键盘enter输入一个Option*/constInputSelect:FC<{defaultOptio......
  • 52 Things: Number 47: What is the Fiat-Shamir transform?
    52Things:Number47:WhatistheFiat-Shamirtransform?52件事:47号:菲亚特沙米尔的转型是什么? Thisisthelatestinaseriesofblogpoststoaddressthelistof'52ThingsEveryPhDStudentShouldKnowToDoCryptography':asetofquestionscompiledtogi......