使用 JavaScript 访问“发布”数据或检查使用哪个提交按钮提交表单

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13950921/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 20:17:04  来源:igfitidea点击:

Access 'post' data using JavaScript or check which submit button was used to submit the form

javascripthtmlajax

提问by Matthew

Consider a simple form with 2 submit buttons

考虑一个带有 2 个提交按钮的简单表单

<form method="post">
 <button type="submit" name="command" value="cancel">Cancel Order</button>
 <button type="submit" name="command" value="proceed">Save Order</button>
</form>

Once submitted, the server will know which submit button was used to submit the form by checking the value for command. Great!

提交后,服务器将通过检查 的值知道使用哪个提交按钮提交表单command。伟大的!

In this case, I am using the onsubmitevent handler of the form to preprocess and send the form data via AJAX. Like this: <form method="post" onsubmit="return ajaxSubmit(this);">

在这种情况下,我使用onsubmit表单的事件处理程序来预处理并通过 AJAX 发送表单数据。像这样:<form method="post" onsubmit="return ajaxSubmit(this);">

I'm using this ajaxSubmitfunction as a general way to check through any supplied form's elements and send the data via Ajax instead. This works fine for determining the value of text fields, if checkboxes are "checked", which radio is selected in a group, etc. The only thing it seems to get wrong (because I'm not sure how to check this) is which submit button was used to submit the form. i.e There is nothing in myForm["command"]to tell which of the 2 command buttons was actually used.

我将此ajaxSubmit函数用作检查任何提供的表单元素并通过 Ajax 发送数据的通用方法。这适用于确定文本字段的值,如果复选框被“选中”,在组中选择了哪个收音机等等。它似乎唯一出错(因为我不知道如何检查这个)是哪个提交按钮用于提交表单。即没有任何东西myForm["command"]可以说明实际使用了 2 个命令按钮中的哪一个。

Instead, is there a way to access the same 'post' data that the server receives with JavaScript before it is sent?

相反,有没有办法访问服务器在发送之前使用 JavaScript 接收到的相同“发布”数据?

Otherwise, is this just a flaw I need to work around? What's the best way?

否则,这只是我需要解决的缺陷吗?最好的方法是什么?

Edit:Since all modern browsers will pass the name/value of the button used to submit the form (along with the other relevant parts like which option is selected from a group, checked checkbox name/values, etc.) can anyone explain why there is no way to access this data directly before it is sent to the server? Is there a reason why we shouldn't be able to?

编辑:由于所有现代浏览器都会传递用于提交表单的按钮的名称/值(以及其他相关部分,例如从组中选择哪个选项、选中的复选框名称/值等)任何人都可以解释为什么有有没有办法在发送到服务器之前直接访问这些数据?有什么理由让我们不能这样做吗?

回答by T.J. Crowder

Instead, is there a way to access the same 'post' data that the server receives with JavaScript before it is sent?

相反,有没有办法访问服务器在发送之前使用 JavaScript 接收到的相同“发布”数据?

Not that exact data, no.

不是那个确切的数据,不是。

The usual way to know which submitbutton was pressed is (unfortunately) to attach clickhandlers to the buttons and have them set a variable (or the value of a hiddenfield), which you can then check in your submitevent handler.

知道哪个submit按钮被按下的常用方法是(不幸的是)将click处理程序附加到按钮并让它们设置一个变量(或hidden字段的值),然后您可以检查submit事件处理程序。

Since you're using old-style DOM0 event handler attributes, probably the hiddenfield fits better with what you're doing:

由于您使用的是旧式 DOM0 事件处理程序属性,因此该hidden字段可能更适合您的操作:

<form method="post">
 <input type="hidden" name="submitclicked" value="">
 <button type="submit" name="command" value="cancel" onclick="submitClick(this);">Cancel Order</button>
 <button type="submit" name="command" value="proceed" onclick="submitClick(this);">Save Order</button>
</form>

...where submitClicklooks like this:

...submitClick看起来像这样:

function submitClick(button) {
    button.form.submitclicked.value = button.value;
}

...but I do recommend looking into using DOM2-style event handlers instead, or at least attaching DOM0 handlers in code blocks, as you can avoid creating global functions, share data without creating global variables, etc.

...但我确实建议考虑使用 DOM2 样式的事件处理程序,或者至少在代码块中附加 DOM0 处理程序,因为您可以避免创建全局函数、共享数据而不创建全局变量等。



Just to be clear, you don't have to specify an onclickattribute on every element, the only reason I did that above is because you were using DOM0 handlers.

需要明确的是,您不必为onclick每个元素指定一个属性,我在上面这样做的唯一原因是因为您使用了 DOM0 处理程序。

The better way to handle it is with event bubbling. Since the clickevent bubbles up to the form from its descendant controls, including the submit buttons, you can hook the event on the form and then look to see if it occurred on a submit button and, if so, what that button's valueis.

处理它的更好方法是使用事件冒泡。由于click事件从其后代控件(包括提交按钮)向上冒泡到表单,因此您可以将事件挂接到表单上,然后查看它是否发生在提交按钮上,如果是,那么该按钮value是什么。

For instance, here with a DOM0 handler, attached dynamically to the form, which will alert the value of the submit button clicked:

例如,这里有一个动态附加到表单的 DOM0 处理程序,它将提醒单击的提交按钮的值:

var form = document.getElementById("theForm");
form.onclick = function(e) {
  // Get the event
  e = e || window.event;

  // Did it originate in an input[type=submit]?
  if (e.target.tagName === "INPUT" &&
      e.target.type === "submit") {
    // Yes
    alert(e.target.value);
  }
};

Live Example| Source

现场示例| 来源

Or using DOM2 handlers on any modern browser (not IE8 or earlier, but it would be easy to add attachEventfor those, which does much the same thing addEventListenerdoes [and predates it]):

或者在任何现代浏览器上使用 DOM2 处理程序(不是 IE8 或更早版本,但很容易为它们添加attachEvent,这与addEventListener[并且早于它]所做的事情大致相同):

document.getElementById("theForm").addEventListener("click", function(e) {
  // Did it originate in an input[type=submit]?
  if (e.target.tagName === "INPUT" &&
      e.target.type === "submit") {
    // Yes
    alert(e.target.value);
  }
}, false);

Live Example| Source

现场示例| 来源

Or using a library to make it easier (here it's jQuery, but most of them have this feature, which is called event delegation):

或者使用一个库来使它更容易(这里是 jQuery,但它们中的大多数都具有此功能,称为事件委托):

$("#theForm").delegate("input[type=submit]", "click", function() {
  alert(this.value);
  return false;
});

Live Example| Source(I'm using delegatethere because I like the clarity; with recent versions of jQuery, you coulduse the hyper-overloaded on, but it's less clear. If you choose to, note that the order of arguments is different.)

现场示例| (我使用delegate那里是因为我喜欢清晰;使用最新版本的 jQuery,您可以使用 hyper-overloaded on,但不太清楚。如果您选择,请注意参数的顺序不同。)

The point here being that it's not complicated, difficult, or particularly cumbersome.

这里的重点是它并不复杂、困难或特别麻烦。

Re your ending question of your edit:

重新你的编辑结束问题:

...can anyone explain why there is no way to access this data directly before it is sent to the server?

...谁能解释为什么在将数据发送到服务器之前无法直接访问这些数据?

Probably not, no. It's important to understand that a lot of this stuff just evolved. The submit button's value being sent with the form is an HTML thing, apparently when doing the DOM HTML forms module, it just didn't occur to anyone to say "Hey, we should have a property on the form that only exists during the form submission event that tells you what submitted the form." It probably shouldhave occurred to someone, but apparently, it didn't.

可能不是,不是。重要的是要了解很多这样的东西刚刚进化。与表单一起发送的提交按钮的值是一个 HTML 的东西,显然在做 DOM HTML 表单模块时,只是没有人说“嘿,我们应该在表单上有一个只存在于表单中的属性提交事件,告诉您提交表单的内容。” 有人可能应该想到它,但显然,它没有。

回答by Sych

Another solution is to use a radio button instead of a submit button (you will have to design the radio to look as a button, though).

另一种解决方案是使用单选按钮而不是提交按钮(不过,您必须将单选按钮设计为看起来像按钮)。

After submitting, the value of the field should be the one that was clicked. You can fetch the selected option by using jQuery's $("[name=command]:selected]"), or $("#theForm").serialize()

提交后,该字段的值应该是被点击的那个。您可以使用 jQuery 的 获取选定的选项$("[name=command]:selected]"),或者$("#theForm").serialize()

<form method="post" onsubmit="return ajaxSubmit(this);" id="theForm">
 <input type="radio" name="command" value="cancel" id="cancel" onClick="document.getElementById('theForm').submit();">
 <label for="cancel">Cancel Order</label>

 <input type="radio" name="command" value="proceed" id="proceed" onClick="document.getElementById('theForm').submit();">
 <label for="proceed">Save Order</label>
</form>

回答by Sych

I think you can work this around by DELETING the other button, the one that that was not clicked. After that, you can run jQuery's serialize(), or access the value of the button that is left by any other means.

我认为你可以通过删除另一个按钮来解决这个问题,那个按钮没有被点击。之后,您可以运行 jQuery 的 serialize(),或通过任何其他方式访问按钮的值。

The code would be:

代码将是:

<form method="post">
 <button type="submit" id=cancel name="command" value="cancel" onclick="document.getElementByid('submit').remove();submitClick(this);">Cancel Order</button>
 <button type="submit" id=submit name="command" value="proceed" onclick="document.getElementByid('cancel').remove();submitClick(this);">Save Order</button>
</form>

回答by Mihai Danila

All reasonable, but if you're going to go as far as attaching click handlers on all your submit buttons, it makes less sense to go through the hoops of the submit capability to manage your submission details.

一切都是合理的,但是如果您打算在所有提交按钮上附加点击处理程序,那么通过提交功能的箍来管理您的提交详细信息就没有意义了。

Just make it so that the click handlers trigger a form submit while passing sufficient contextual information into the mix. Wait, click handlers typically tell you the source of the click already (there's your contextual information), especially if using some jQuery-ish framework.

只需让点击处理程序触发表单提交,同时将足够的上下文信息传递到组合中即可。等等,点击处理程序通常已经告诉您点击的来源(有您的上下文信息),尤其是在使用一些 jQuery 风格的框架时。

So instead of:

所以而不是:

<form onsubmit="doSubmit()" ...>
<input type="submit" onclick="updateSourceTo('cancel');" ... />
<input type="submit" onclick="updateSourceTo('submit');" ... />

Use:

利用:

<form ...>
<input type="button" onclick="doSubmit('cancel');" ... />
<input type="button" onclick="doSubmit('submit');" ... />

Or, if you'll be detecting the source by looking at the click event target:

或者,如果您将通过查看点击事件目标来检测源:

<form ...>
<input type="button" onclick="handleSubmitButtonClick();" ... />
<input type="button" onclick="handleSubmitButtonClick();" ... />

For the nitty-gritty details of handleSubmitButtonClick, I should mention form.submit()and things like jQuery's event.target.

对于 handleSubmitButtonClick 的细节,我应该提到form.submit()和 jQuery 的event.target 之类的东西。

I admit that keeping with the submit-onsubmit paradigm promotes a certain purism to form handling, but IMO you're already stepping into non-purist lands with the use of two submit buttons.

我承认,与提交时提交范式保持一致促进了某种纯粹主义的形式处理,但 IMO 您已经通过使用两个提交按钮进入了非纯粹主义领域。