当用户单击提交按钮时,表单会正常提交,但是如果用户故意快速点击多次,它将会多次提交,这会导致数据库中出现重复数据。
这种问题的解决方案是什么?
更新:我看到有些建议是禁用提交按钮。这可以防止表单被多次提交,但问题是我的页面中的表单元素没有刷新,如果我禁用它,用户将无法再次提交,禁用15秒可能有效,但这是解决这个问题的正确方法吗?
Use setTimeout()
to disable the button after a few milliseconds so that its name-value pair get sent anyway. 50ms is an affordable amount.
$("form").submit(function() {
var form = this;
setTimeout(function() {
$(':submit', form).attr('disabled', true);
}, 50);
});
Copy the name-value pair of the actually pressed submit button into a hidden input of the form. This is a bit trickier since this information isn't available in the submit
event of the <form>
. You need to let the $(document)
capture the last clicked element.
$("form").submit(function() {
$(':submit', this).attr('disabled', true);
$(this).append($('<input/>').attr({
type: 'hidden',
name: $.lastClicked.name,
value: $.lastClicked.value
}));
});
$(document).click(function(e) {
e = e || event;
$.lastClicked = e.target || e.srcElement;
});
更新:根据您的更新:
好的,我看到有些建议是禁用提交按钮。这可以防止重复提交,但问题是我的页面中的表单元素没有刷新,如果我禁用它,用户将无法再次提交它,禁用它15秒可能有效,但这是解决这个问题的正确方法吗?
所以你实际上正在触发一个ajax请求。在jQuery的ajax函数的回调处理程序中,您可以重新启用按钮。假设您正在使用jQuery.post
:
$("form").submit(function() {
// Disable buttons here whatever way you want.
var form = this;
$.post('some/url', function(data) {
// Re-enable buttons at end of the callback handler.
$(':submit', form).attr('disabled', false);
});
});
$("form").submit(function() {
$(':submit',this).attr('disabled','disabled');
$('selector').load(url,function(){
$(':submit',this).removeAttr('disabled');
})
});
$('selector')
是什么吗?... OP 没有提供太多代码(只有 .submit()
)... 所以我假设... 如果文本框处于焦点状态并按下回车键,则会提交,但这还取决于 OP 的代码... - Reigel Gallarde试试这个:
$("form").submit(function() {
var form = this;
setTimeout(function() {
$(':submit', form).attr('disabled', true);
}, 50);
setTimeout(function() {
$(':submit', form).removeAttr('disabled');
}, 1000);
});
真正的问题在于数据库层,必须设计防止重复的机制。以下是一个通用但有点丑陋的解决方案:
当您最初呈现页面时,可以创建一个GUID,比如操作ID,并将其放入视图状态中。当您在服务器端处理事件时,只需将此GUID插入到表中,例如OngoingOperations,其中它是主键。第一次插入将成功,其他插入将失败。当然,为了更加用户友好,您可以跳过后续操作并返回第一个操作的状态。
OngoingOperations表可能如下所示:
CREATE TABLE OngoingOperations( OperationID uniqueidentifier primary key, OperationDate datetime default getdate(), OperationStatus nvarchar(max) );
OperationStatus - 是状态消息或任何要从后续提交返回给客户端的数据。在这里,您可以使用标志(ok或not)或详细消息-根据您的意愿。
此表需要收集旧记录,例如每小时删除2个或更多小时前完成的操作。
Anton Burtsev