使用jquery防止重新提交表单

发布于 2024-09-01 15:57:44 字数 244 浏览 3 评论 0原文

我使用jquery的.submit()来拦截用户的提交事件,但是我发现了一个问题。

当用户单击提交按钮时,表单会正常提交,但如果用户故意快速单击多次,则会提交多次,这会导致数据库中的数据重复。

此类问题的解决办法是什么?

更新:嗯,我看到一些建议说禁用提交按钮。这应该可以防止表单被多次提交,但问题是我的页面中的表单元素没有刷新,如果我禁用它,用户将无法再提交它,禁用它 15 秒可能会起作用,但这是解决这个问题的正确方法吗?

I use jquery's .submit() to intercept user's submit event, however I found a problem.

When the user single click the submit button, the form is submitted normally, but if a user deliberately fast click it multiple times, it will submit multiple times, which will cause duplicated data in the database.

What's the solution for this kind of problem ?

Update: Well, I see some of the advice said disabling the submit button. This should prevent the form being submitted multiple times, but the problem is the form element in my page isn't refreshed, if I disable it the user won't be able to submit it anymore, disabling it for 15s may work, but is this the right way to solve this problem ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

昔日梦未散 2024-09-08 15:57:44

禁用提交按钮确实是正确的方法。

然而,在很多情况下,要执行的服务器端逻辑取决于请求参数映射中所讨论的提交按钮的名称/值对的存在。特别是在基于服务器端组件的 MVC 框架(如 MS ASP.NET 和 Sun JSF)中,而且在具有多个提交按钮的“简单”表单中。按下的提交按钮的名称-值对是确定要执行的操作所必需的。禁用该按钮将使其名称-值对完全消失在请求参数映射中,并且服务器端可能不会采取任何操作或执行错误的操作。

基本上有两种方法可以解决这个问题:

  1. 使用setTimeout()在几毫秒后禁用按钮,以便无论如何都会发送其名称-值对。 50ms 是一个可以承受的量。

    $("表单").submit(function() {
        var 形式 = this;
        设置超时(函数(){
            $(':提交', 表单).attr('禁用', true);
        }, 50);
    });
    
  2. 将实际按下的提交按钮的名称/值对复制到表单的隐藏输入中。这有点棘手,因为此信息在

    submit 事件中不可用。您需要让 $(document) 捕获最后单击的元素。

    $("表单").submit(function() {
        $(':提交', this).attr('禁用', true);
        $(this).append($('<输入/>').attr({
            类型:'隐藏',
            名称:$.lastClicked.name,
            值:$.lastClicked.value
        }));
    });
    
    $(文档).click(函数(e) {
        e = e ||事件;
        $.lastClicked = e.target || e.srcElement;
    });
    

更新:根据您的更新:

嗯,我看到一些建议说禁用提交按钮。这应该可以防止多次提交,但问题是我的页面中的表单元素没有刷新,如果我禁用它,用户将无法再提交它,禁用它 15 秒可能会起作用,但这是吗?解决这个问题的正确方法是什么?

所以你实际上是在发出一个ajaxal请求。您只需在 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);
    });
});

Disabling the submit button is indeed the way to go.

However, in a lot of cases the server side logic to be executed depends on the presence of the name-value pair of the submit button in question in the request parameter map. Especially in server side component based MVC frameworks like MS ASP.NET and Sun JSF, but also in "simple" forms having more than one submit button. The name-value pair of the pressed submit button is mandatory to determine the action to be executed. Disabling the button would make its name-value pair to completely disappear in the request parameter map and the server side may not take any action or execute the wrong action.

There are basically 2 ways to go around this:

  1. 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);
    });
    
  2. 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;
    });
    

Update: as per your update:

Well, I see some of the advice said disabling the submit button. This should prevent the from submit multiple times, but the problem is the form element in my page isn't refreshed, if I disable it the user won't be able to submit it anymore, disabling it for 15s may work, but is this the right way to solve this problem ?

So you're actually firing an ajaxical request. You could just re-enable the button(s) in the callback handler of the jQuery's ajax function. Assuming you're using 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);
    });
});
旧梦荧光笔 2024-09-08 15:57:44

尝试禁用表单提交上的提交按钮...

$("form").submit(function() {
    $(':submit',this).attr('disabled','disabled');
    $('selector').load(url,function(){
       $(':submit',this).removeAttr('disabled');
    })
});​

快速演示

try disabling the submit button on form submit....

$("form").submit(function() {
    $(':submit',this).attr('disabled','disabled');
    $('selector').load(url,function(){
       $(':submit',this).removeAttr('disabled');
    })
});​

quick demo

若相惜即相离 2024-09-08 15:57:44

真正的问题在于数据库层,它的设计必须防止重复。这是一个通用但有点丑陋的解决方案:

当您最初呈现页面时,您可以创建一个 GUID。比如说,操作 ID。并将其放入视图状态。当您在服务器端处理事件时,只需将此 guid 插入表中,例如 OngoingOperations,其中它是主键。第一个插入会成功,其他都会失败。当然,为了更加用户友好,您可以跳过后续操作并返回第一个操作的状态。

OngoingOperations 表可能如下所示:

CREATE TABLE OngoingOperations(
OperationID唯一标识符主键,
OperationDate日期时间默认getdate(),
操作状态 nvarchar(最大值)
);

OperationStatus - 是状态消息或从后续提交返回给客户端的任何数据。在这里,您可以根据需要使用标志(可以或不行)或详细消息。

该表需要收集旧记录,假设每小时删除 2 小时或更长时间之前完成的操作。

安东·布尔采夫

The real problem lies at database layer it must be designed to prevent duplications. here is a universal but a bit ugly solution:

When you initially renders a page you can create a GUID. Say, operation ID. and put it into a viewstate. When you processing an event on server side just insert this guid in a table, say OngoingOperations where it is a primary key. The first insertion will succeed, other will fail. Of cource, to be more user-friendly you can just skip subsequent operations and return status of the first one.

The OngoingOperations table may look as follows:

CREATE TABLE OngoingOperations(
OperationID uniqueidentifier primary key,
OperationDate datetime default getdate(),
OperationStatus nvarchar(max)
);

OperationStatus - is status message or any data to return to client from subsequent submissions. Here you can use a flag (ok or not) or a detailed message - as you wish.

this table requires collection of old records, say every hour you just delete operations with that completed 2 or more hours before.

Anton Burtsev

东北女汉子 2024-09-08 15:57:44

试试这个:

$("form").submit(function() {
    var form = this;
    setTimeout(function() {
        $(':submit', form).attr('disabled', true);
    }, 50);

    setTimeout(function() {
        $(':submit', form).removeAttr('disabled');
    }, 1000);
});

Try this:

$("form").submit(function() {
    var form = this;
    setTimeout(function() {
        $(':submit', form).attr('disabled', true);
    }, 50);

    setTimeout(function() {
        $(':submit', form).removeAttr('disabled');
    }, 1000);
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文