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

有时候响应很慢时,可能会多次点击提交button。

如何防止这种情况发生?

在表单提交之后,使用不显眼的JavaScript来禁用表单上的提交事件。 这里是一个使用jQuery的例子。

编辑:修正提交表单的问题,而不点击提交button。 谢谢,一class。

$("form").submit(function() { $(this).submit(function() { return false; }); return true; }); 

我尝试vanstee的解决scheme,随着asp mvc 3不显眼的validation,如果客户端validation失败,代码仍然运行,表单提交被禁用的好。 纠正字段后,我无法重新提交。 (见bjan的评论)

所以我修改了vanstee的脚本

 $("form").submit(function () { if ($(this).valid()) { $(this).submit(function () { return false; }); return true; } else { return false; } }); 

客户端的表单提交控制可以通过让onsubmit处理程序隐藏提交button并用一个加载animation代替。 这样,用户在他的动作(点击)发生的同一个地点立即得到视觉反馈。 同时,您也可以防止表单被另外提交。

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

另一方面,llimllib提出了一个非常有效的观点。 所有表单validation都必须发生在服务器端 这包括多个提交检查。 永远不要相信客户! 这不仅是一种情况,如果javascript被禁用。 您必须记住所有的客户端代码都可以修改。 这是有点难以想象,但HTML / JavaScript谈话到您的服务器不一定是你写的HTML / JavaScript。

正如llimllib所build议的那样,用一个唯一的表单标识符来生成表单,并把它放在一个隐藏的input字段中。 存储该标识符。 当收到表格数据时,只有当标识符匹配时才处理。 (也将标识符链接到用户会话并与之相匹配,以获得额外的安全性。)数据处理后删除标识符。

当然,有一段时间,你需要清理从未提交任何表单数据的标识符。 但很可能你的网站已经采用某种“垃圾收集”机制。

这是简单的方法来做到这一点:

 <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> 
 <form onsubmit="if(submitted) return false; submitted = true; return true"> 

单击后立即禁用提交button。 确保你正确地处理validation。 也为所有处理或数据库操作保留一个中间页面,然后redirect到下一页。 这确保刷新第二页不做另一个处理。

散列当前时间,使其成为窗体上的隐藏input。 在服务器端,检查每个表单提交的哈希值; 如果你已经收到这个散列,那么你有重复的提交。

编辑:依靠JavaScript是不是一个好主意,所以你们都可以保持upvoting这些想法,但一些用户将不会启用它。 正确的答案是不信任服务器端的用户input。

使用JQuery你可以这样做:

 $('input:submit').click( function() { this.disabled = true } ); 

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

您还可以显示一个进度条或微调框以指示表单正在处理中。

我知道你用'javascript'标记了你的问题,但是这里有一个解决scheme不依赖于javascript:

这是一个名为PRG的webapp模式,这里有一篇很好的文章来描述它

您可以通过以下方式防止多次提交:

 var Workin = false; $('form').submit(function() { if(Workin) return false; Workin =true; // codes here. // Once you finish turn the Workin variable into false // to enable the submit event again Workin = false; }); 

你可以尝试safeform jQuery插件。

 $('#example').safeform({ timeout: 5000, // disable form on 5 sec. after submit submit: function(event) { // put here validation and ajax stuff... // no need to wait for timeout, re-enable the form ASAP $(this).safeform('complete'); return false; } }) 

这个问题最简单的答案就是这样问:“有时候响应很慢,可能会多次点击提交button,如何防止这种情况发生?

只需禁用表单提交button,就像下面的代码。

 <form ... onsubmit="buttonName.disabled=true; return true;"> <input type="submit" name="buttonName" value="Submit"> </form> 

它将禁用提交button,第一次点击提交。 另外如果你有一些validation规则,那么它会正常工作。 希望它会有所帮助。

在客户端 ,一旦用javascript代码提交表单(如@vanstee和@chaos提供的方法),应该禁用提交button。

但是,对于networking滞后或JavaScript禁用的情况,您不应该依赖JS来防止这种情况的发生。

所以, 在服务器端 ,你应该检查来自同一客户端的重复提交,并省略重复的,这似乎是来自用户的错误尝试。

对我来说最简单最优雅的解决scheme:

 function checkForm(form) // Submit button clicked { form.myButton.disabled = true; form.myButton.value = "Please wait..."; return true; } <form method="POST" action="..." onsubmit="return checkForm(this);"> ... <input type="submit" name="myButton" value="Submit"> </form> 

链接更多…

防止多次提交的最好方法是只传递方法中的buttonid。

  function DisableButton() { document.getElementById("btnPostJob").disabled = true; } window.onbeforeunload = DisableButton; 

要做到这一点使用JavaScript是有点容易。 以下是将提供所需function的代码:

 $('#disable').on('click', function(){ $('#disable').attr("disabled", true); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button id="disable">Disable Me!</button> 

最简单的解决scheme是,禁用点击button,操作完成后启用它。 检查jsfiddle上的类似解决scheme:

 [click here][1] 

你可以find这个答案的其他解决scheme。

这对我来说很好。 它提交农场,使button禁用,并在2秒后激活button。

 <button id="submit" type="submit" onclick="submitLimit()">Yes</button> function submitLimit() { var btn = document.getElementById('submit') setTimeout(function() { btn.setAttribute('disabled', 'disabled'); }, 1); setTimeout(function() { btn.removeAttribute('disabled'); }, 2000);} 

在ECMA6 Syntex中

 function submitLimit() { submitBtn = document.getElementById('submit'); setTimeout(() => { submitBtn.setAttribute('disabled', 'disabled') }, 1); setTimeout(() => { submitBtn.removeAttribute('disabled') }, 4000);} 

在你的form.It中使用这个代码将处理多个点击。

 <script type="text/javascript"> $(document).ready(function() { $("form").submit(function() { $(this).submit(function() { return false; }); return true; }); }); </script> 

它会肯定的工作。