如何防止表单从客户端多次提交?

omg*_*omg 89 javascript submit

有时,当响应很慢时,可能会多次单击"提交"按钮.

如何防止这种情况发生?

小智 96

使用不显眼的javascript在表单提交后禁用表单上的提交事件.这是一个使用jQuery的例子.

编辑:修复了提交表单而不单击提交按钮的问题.谢谢,ichiban.

$("body").on("submit", "form", function() {
    $(this).submit(function() {
        return false;
    });
    return true;
});
Run Code Online (Sandbox Code Playgroud)

  • 我试着使用不显眼的验证和MVC来解决这个问题.首先调用JS,它总是返回false,然后调用验证.因此,如果我的表单有一些验证错误,表单永远不会被提交!! (14认同)
  • 工作真的很棒.我还想禁用提交按钮并替换提交按钮文本以显示用户提示.`$(this).find("input [type ='submit']").attr('disabled','disabled').val('submiting'); 返回true; });` (6认同)
  • 如果通过按文本框​​中的输入提交表单怎么办? (4认同)
  • 完美的工作! (3认同)
  • 你甚至需要`return true`吗?我认为初始提交应该没有这个. (2认同)

小智 39

我尝试了vanstee的解决方案以及asp mvc 3不显眼的验证,如果客户端验证失败,代码仍然运行,表单提交被禁用.纠正字段后我无法重新提交.(见bjan的评论)

所以我修改了vanstee的脚本,如下所示:

$("form").submit(function () {
    if ($(this).valid()) {
        $(this).submit(function () {
            return false;
        });
        return true;
    }
    else {
        return false;
    }
});
Run Code Online (Sandbox Code Playgroud)


Rob*_*Rob 24

通过让onsubmit处理程序隐藏提交按钮并将其替换为加载动画,可以非常优雅地实现客户端表单提交控制.这样,用户可以在他的动作(点击)发生的同一地点获得即时视觉反馈.同时,您可以防止另一次提交表单.

如果您通过XHR提交表单,请记住您还必须处理提交错误,例如超时.您必须再次显示提交按钮,因为用户需要重新提交表单.

另一方面,llimllib提出了一个非常有效的观点.所有表单验证必须在服务器端进行.这包括多次提交检查.永远不要相信客户!这不仅是javascript被禁用的情况.您必须记住,可以修改所有客户端代码.这有点难以想象,但与您的服务器通信的html/javascript不一定是您编写的html/javascript.

正如llimllib建议的那样,生成具有该表单唯一标识符的表单并将其放入隐藏的输入字段中.存储该标识符.当接收表单数据时,仅在标识符匹配时处理它.(还将标识符链接到用户会话并匹配,以获得额外的安全性.)数据处理后删除标识符.

当然,偶尔,您需要清理从未提交任何表单数据的标识符.但很可能你的网站已经采用了某种"垃圾收集"机制.


cha*_*aos 15

<form onsubmit="if(submitted) return false; submitted = true; return true">
Run Code Online (Sandbox Code Playgroud)

  • 使用`<form onsubmit ="return(typeof submitted =='undefined')?(submitted = true):!提交">`,或者在脚本的正确位置写入`var submitted = false;`,以避免以下错误:`未捕获的ReferenceError:提交未定义`. (6认同)

ich*_*ban 14

这是一个简单的方法:

<form onsubmit="return checkBeforeSubmit()">
  some input:<input type="text">
  <input type="submit" value="submit" />
</form>

<script type="text/javascript">
  var wasSubmitted = false;    
    function checkBeforeSubmit(){
      if(!wasSubmitted) {
        wasSubmitted = true;
        return wasSubmitted;
      }
      return false;
    }    
</script>
Run Code Online (Sandbox Code Playgroud)


Sho*_*ban 8

单击后立即禁用提交按钮.确保正确处理验证.还要为所有处理或数据库操作保留一个中间页面,然后重定向到下一页.这样可以确保刷新第二页不会执行其他处理.


Imr*_*han 6

对这个问题最简单的回答是:“有时响应缓慢,可能会多次单击提交按钮。如何防止这种情况发生?”

只需禁用表单提交按钮,如下面的代码。

<form ... onsubmit="buttonName.disabled=true; return true;">
  <input type="submit" name="buttonName" value="Submit">
</form>
Run Code Online (Sandbox Code Playgroud)

它将禁用提交按钮,第一次点击提交。此外,如果您有一些验证规则,那么它会正常工作。希望它会有所帮助。


lli*_*lib 5

哈希当前时间,使其成为表单上的隐藏输入.在服务器端,检查每个表单提交的哈希值; 如果你已经收到了那个哈希,那么你有一个重复提交.

编辑:依赖javascript不是一个好主意,所以你们都可以继续推动这些想法,但有些用户不会启用它.正确答案是不信任服务器端的用户输入.

  • @moneypenny你的第一个异议是假的,散列将是表单发送给用户的时间,而不是他们提交的时间.如果你真的担心第二个,你有很多选择.将他们的会话ID添加到您散列的字符串,和/或检查表单的所有字段是否完全相同; 两个用户可能没有提交完全相同的表单. (2认同)
  • "过度"是旁观者的眼睛.如果您*确实*需要防止重复提交表单,则至少部分解决方案必须是服务器端."你不能相信用户." (2认同)

Ton*_*orf 5

您也可以显示进度条或微调器以指示表单正在处理。


Bor*_*éry 5

使用JQuery,您可以:

$('input:submit').click( function() { this.disabled = true } );
Run Code Online (Sandbox Code Playgroud)

&

   $('input:submit').keypress( function(e) {
     if (e.which == 13) {
        this.disabled = true 
     } 
    }
   );
Run Code Online (Sandbox Code Playgroud)