FormData 不包括按钮的值

问题描述 投票:0回答:4

考虑以下片段:

$('#myBtn').click(function(e) {
    e.preventDefault();
    
    var formElement = $(this).closest('form')[0];
    var request = new XMLHttpRequest();
    request.open("POST", "https://posttestserver.com/post.php");
    request.send(new FormData(formElement));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="POST" action="https://posttestserver.com/post.php">
  <input type="text" name="wtf" />
  <button type="submit" name="lol" value="cats" id="myBtn">
    Huh
  </button>
</form>

(打开您的开发人员工具并观察 HTTP 请求。)

当您单击按钮时,您在文本框中输入的任何文本都会包含在 POST 请求中。但是,按钮本身的

lol=cats
对不是。

如何让 FormData 包含按钮提供的数据?

javascript jquery html form-data
4个回答
10
投票

因为对

FormData
的构造函数的调用不知道它是由点击提交按钮触发的(更不用说它是哪个提交按钮),并且因为您只希望包含 used 提交按钮的值,提交按钮不包含在发布的数据中。您可以使用
FormData.append
包含所需的对。

$('#myBtn').click(function(e) {
    e.preventDefault();
    var formElement = $(this).closest('form')[0];
    var formData = new FormData(formElement);
    formData.append("lol","cats");
    var request = new XMLHttpRequest();
    request.open("POST", "https://posttestserver.com/post.php");
    request.send(formData);
});
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
 <form method="POST" action="https://posttestserver.com/post.php">
      <input type="text" name="wtf" />
      <button type="submit" id="myBtn">
        Huh
      </button>
    </form>


7
投票

如您所述,FormData 无法知道按钮的名称。但是当你抓到表单提交时,你可以通过事件上的

submitter
属性获取名称

const form = document.querySelector("form")

form.addEventListener("submit", ev => {
    ev.preventDefault()

    const data = {}

    for (const field of new FormData(form)) {
        data[field[0]] = field[1]
    }

    // NB: we are setting "none" as a fallback in case the form
    // has been submitted without clicking a button, e.g. by 
    // hitting enter in an input field.

    data.action = ev.submitter ? ev.submitter.name : "none"

    // … and so on
})

4
投票

如果我在 Safari 中执行

new FormData(event.target)
,我会得到按钮数据。在 Chrome 中我没有。在 Safari 中,
event.submitter
始终是
none
,但在 Chrome 中它有效。所以好像我只是这样做:

let data = new FormData(event.target);
if (event.submitter) {
    data.append(event.submitter.name, event.submitter.value)
}

然后我在 Safari 和 Chrome 中都得到了所需的行为。


1
投票

规范已更新以支持

submitter
传递给
FormData
,并且功能在最新版本的主要浏览器(ChromeFirefoxSafari)中可用。对于不支持的浏览器,您可以使用 formdata-submitter-polyfill 包。这样你就可以可靠地创建
FormData
对象来匹配等效的原生表单提交(即包括提交按钮的条目,如果合适的话)。

提交处理程序中的基本用法如下所示:

myform.addEventListener("submit", (e) => {
  e.preventDefault();
  const formData = new FormData(e.target, e.submitter);
  // do something with formData...
});

根据您的目标浏览器版本,您可能还想使用 event-submitter-polyfill 包,它确保

submitter
属性设置在
SubmitEvent
.

© www.soinside.com 2019 - 2024. All rights reserved.