How to prevent form from submitting multiple times from client side?

有时,当响应较慢时,可以多次单击提交按钮。

How to prevent this from happening?

157082 次浏览
<form onsubmit="if(submitted) return false; submitted = true; return true">

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

创建一个唯一标识符(例如,您可以散列当前时间) ,并将其作为表单上的隐藏输入。在服务器端,检查每个表单提交的唯一标识符,如果你已经收到了散列,那么你就得到了一个重复提交。用户重新提交的唯一方法是重新加载表单页。

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

You could also display a progress bar or a spinner to indicate that the form is processing.

使用 JQuery 你可以做到:

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

&

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

这里有一个简单的方法:

<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>

在表单已经提交后,使用 Unobtrusive JavaScript 禁用表单上的提交事件。下面是一个使用 jQuery 的示例。

编辑: 修正了没有点击提交按钮就提交表单的问题。谢谢,一条。

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

客户端表单提交控制可以通过让 onsubmit 处理程序隐藏提交按钮并用加载动画替换它来实现。这样,用户就可以在他的动作(点击)发生的同一地点得到即时的视觉反馈。同时,您可以防止再次提交表单。

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

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

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

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

我知道你用“ javascript”标记了你的问题,但这里有一个完全不依赖 javascript 的解决方案:

这是一个名为 PRG的 web 应用程序模式,下面是一个描述它的 good article

On the client side, you should disable the submit button once the form is submitted with javascript code like as the method provided by @vanstee and @chaos.

但是有一个问题,网络延迟或 javascript 禁用的情况下,您不应该依赖于 JS 来防止这种情况发生。

因此,在服务器端,您应该检查来自相同客户端的重复提交,并忽略似乎来自用户的错误尝试的重复提交。

你可以试试 安全 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;
}
})

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

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;


});

我尝试了 范斯蒂解和 asp mvc 3低调验证,如果客户端验证失败,代码仍然运行,表单提交永远禁用。我无法在更正字段后重新提交。(见 bjan 的评论)

所以我修改了 Vanstee 的剧本:

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

防止多次提交的最好方法是这样的 只需在方法中传递按钮 id。

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

The most simple answer to this question as asked: "Sometimes when the response is slow, one might click the submit button multiple times. How to prevent this from happening?"

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

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

它将禁用提交按钮,在第一次点击提交。另外,如果您有一些验证规则,那么它将工作得很好。希望能有所帮助。

使用 javascript 做到这一点有点容易,下面的代码将提供所需的功能:

$('#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>

最简单的解决方案是在单击时禁用按钮,在操作完成后启用它。在 jsfiddle 上检查类似的解决方案:

[click here][1]

你可以在这个 回答上找到其他的解决方案。

这对我来说很有用。它提交农场,使按钮禁用,2秒后激活按钮。

<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合成中

function submitLimit() {
submitBtn = document.getElementById('submit');


setTimeout(() => { submitBtn.setAttribute('disabled', 'disabled') }, 1);


setTimeout(() => { submitBtn.removeAttribute('disabled') }, 4000);}

对我来说,最简单、最优雅的解决方案是:

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>

链接更多..。

在表单中使用此代码。它将处理多次单击。

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

一定会成功的。

只是为了在不绕过浏览器输入验证的情况下添加可能的答案

$( document ).ready(function() {
$('.btn-submit').on('click', function() {
if(this.form.checkValidity()) {
$(this).attr("disabled", "disabled");
$(this).val("Submitting...");
this.form.submit();
}
});
});

这允许每2秒提交一次。

$(document).ready(function() {
$('form[debounce]').submit(function(e) {
const submiting = !!$(this).data('submiting');


if(!submiting) {
$(this).data('submiting', true);


setTimeout(() => {
$(this).data('submiting', false);
}, 2000);


return true;
}


e.preventDefault();
return false;
});
})

以前提出的替代方案是:

jQuery('form').submit(function(){
$(this).find(':submit').attr( 'disabled','disabled' );
//the rest of your code
});
<h3>Form</h3>
<form action='' id='theform' >
<div class='row'>
<div class="form-group col-md-4">
<label for="name">Name:</label>
<input type='text' name='name' class='form-control'/>
</div>
</div>
<div class='row'>
<div class="form-group col-md-4">
<label for="email">Email:</label>
<input type='text' name='email' class='form-control'/>
</div>
</div>
<div class='row'>
<div class="form-group col-md-4">
<input class='btn btn-primary pull-right' type="button" value="Submit" id='btnsubmit' />
</div>
</div>
</form>






<script>


$(function()
{
$('#btnsubmit').on('click',function()
{
$(this).val('Please wait ...')
.attr('disabled','disabled');
$('#theform').submit();
});
      

});


</script>

这是一个干净的 Javascript 代码,可以防止多个有效提交:

<script>
var form = document.querySelector('form');
form.onsubmit = function(e){
if(form.reportValidity())
// if form is valid, prevent future submissions by returning false.
form.onsubmit = (e)=> false;
return true;
}
</script>