有没有办法知道 HTML 表单当前是否正在提交?

发布于 2024-09-30 14:34:54 字数 683 浏览 3 评论 0原文

我有一个竞争条件,如果当前正在提交页面上的表单,我不希望发生 AJAX 调用。

我不想更改表单的代码。

我正在考虑将事件处理程序附加到每个表单元素,以便在 onsubmit 时增加计数器,然后在 onreadystatechange 时减少计数器。

然后在 AJAX 调用之前,检查以确保计数器在触发前为零。

然而,有没有更简单的方法,例如(伪代码):

form.isSubmitting 

编辑:

竞争条件不是因为 JavaScript per-say。这是由服务器端响应这些操作的顺序所发生的情况引起的。

为了让您了解更广泛的问题:

表单发布返回时会设置 cookie。 在 AJAX 调用中(需要每 X 秒发生一次)...服务器端(如果表单发布已发生)期望设置 cookie。

有时......

如果表单提交返回(并设置 cookie 客户端)存在延迟,则会触发 AJAX 调用,而不会发回 cookie。

服务器需要 cookie,因为就其而言,表单发布已经成功。

然而,我需要控制客户端以确保按照规定的方式执行操作。

因此,正确的 JavaScript 本身不会导致竞争条件,但是(据我的测试显示)- POST/AJAX 调用的提交和返回在我的特定情况下会导致竞争条件。

I have a race condition in which I do not want an AJAX call to occur, if a form on the page is currently submitting.

I'd rather not alter the code for the form.

I was thinking of attaching event handlers to each of the form elements so that onsubmit it would increment a counter and then on onreadystatechange decrement the counter.

Then before the AJAX call, check to ensure the counter is zero before firing.

However is there an easier way such as (pseudo code):

form.isSubmitting 

EDIT:

The race condition is not because of the JavaScript per-say. It is caused by what happens on the server side on response of the ordering of these actions.

To give you an idea of the broader problem:

A cookie is set when the form post returns.
On the AJAX call (needs to happen every X seconds)... the server-side (if the form post has happened) expects the cookie to be set.

Sometimes....

If there is a delay in the form submission returning (and setting the cookie client side), the AJAX call is triggered without sending the cookie back.

The server expects the cookie, because as far as it is concerned the form post has been successful.

However it is the client side I need to control to ensure the actions are performed in a prescribed way.

So correct JavaScript itself cannot cause race conditions, but (as far as my testing has shown) - the submission and returning of POST/AJAX calls causes a race condition in my particular case.

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

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

发布评论

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

评论(3

鸵鸟症 2024-10-07 14:34:54

网页上的 JavaScript 不存在“竞争条件”,因为只有一个执行线程。如果您想阻止事件处理程序在提交表单后(或实际上在任何时候)执行任何操作,最简单的方法就是设置一些全局可访问的标志。处理程序例程只需检查这一点。当然,在适当的时候清除该标志很重要。

编辑 - 好的,编辑后,您在做什么就更清楚了,但有一点不清楚:表单到底是如何发布的?这是一个“自然”的表单帖子吗?如果是这种情况,整个页面将由响应重新加载。目标可能是一个单独的 吗?

或者表单是由某些其他 AJAX 代码提交的?

  1. 如果浏览器“自然”提交表单,并且我们正在讨论重新加载整个页面,那么这可能是最简单的情况。表单的“提交”处理程序应该简单地设置全局标志,并且通过间隔计时器运行的代码应该在设置标志时的间隔内不执行任何操作。无需担心清除标志,因为无论如何,页面都会被响应破坏。

  2. 如果表单在页面上的 内发布,或者发布到隐藏的 ,那么它几乎与 (1 )除了响应页面需要清除全局标志。具体如何做到这一点取决于应用程序设置涉及的内容,但基本上只是响应中的一些 Javascript 将 top.postingFlag 设置为 false (或其他) .

  3. 如果是单独的 AJAX 代码发布表单,那么您需要在启动 XMLHttpRequest 时设置该标志,并在成功/失败的处理程序中清除它。

在所有情况下,关键是间隔计时器中的代码要监视标志的状态,并避免在设置标志时进行发布。

There are no "race conditions" in Javascript on a web page, because there's just one thread of execution. If you want to prevent event handlers from doing anything after a form has been submitted (or at any time, really), the very simplest thing to do is set some globally-accessible flag. The handler routines just have to check for that. Of course it's important that the flag is cleared when appropriate.

edit — OK after your edit, it's a little more clear what you're doing, but one thing is not clear: how exactly is the form being posted? Is it a "natural" form post? If that's the case, the whole page is going to be reloaded by the response. Is the target a separate <iframe> perhaps?

Or is the form being submitted by some other AJAX code?

  1. If the form is being submitted "naturally" by the browser, and we're talking about a whole page being reloaded, then that's probably the simplest case. The form's "submit" handler should simply set the global flag, and the code running via the interval timer should just do nothing on the intervals when the flag is set. There's no need to worry about clearing the flag, because the page is going to blasted by the response anyway.

  2. If the form is posting within an <iframe> on the page, or posting to a hidden <iframe>, then it's almost the same as (1) except that the response page will need to clear the global flag. Exactly how to do that depends on what the application setup involves, but basically it'll just be some Javascript in the response that sets top.postingFlag to false (or whatever).

  3. If it's separate AJAX code that's posting the form, then you'd set the flag when you start the XMLHttpRequest, and clear it in the handler(s) for success/failure.

In all cases, the key is for code in the interval timer to watch for the state of the flag, and avoid posting when the flag is set.

云巢 2024-10-07 14:34:54

您可以将其添加到表单标记中:

<form ... onsubmit="this.setAttribute('isSubmitting', 'true');">

并且您将能够通过检查该属性来查看它是否正在“提交”。

You can add this to the form tag:

<form ... onsubmit="this.setAttribute('isSubmitting', 'true');">

And you'll be able to see if it's "submitting" by checking that attribute.

别闹i 2024-10-07 14:34:54

是的,可以。

您可以通过 AJAX 调用提交表单。这样您就可以控制 ajaxSendajaxComplete 事件,并使用一个全局变量 var formIsSubmiting = false 作为标志。

在非表单 AJAX 调用之前检查变量的状态,这应该可以防止出现竞争情况。

Yes, that would work.

You can submit the form via an AJAX call. That way you can control the ajaxSend and the ajaxComplete events and have a global variable say var formIsSubmiting = false serving as a flag.

Right before the non-form AJAX call check the status of the variable and that should prevent your race condition.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文