【问题标题】:FormData doesn't include value of buttonsFormData 不包括按钮的值
【发布时间】:2018-06-27 14:51:15
【问题描述】:

考虑以下 sn-p:

$('#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 包含按钮给出的数据?

【问题讨论】:

  • 按钮不是输入类型,因此无法将值传递给 POST 请求
  • 您是否在 Firefox 中进行测试?检查这个问题:stackoverflow.com/questions/38277900/…
  • @RoryMcCrossan:Chrome 但在 FF 中相同
  • @RoryMcCrossan:接受的答案似乎准确地描述和解​​释了这里发生的事情
  • 在这种情况下,其他浏览器可能已更新以遵循该标准。老实说,我一直发现在请求中发送提交按钮值的支持有点不稳定。如果可能,我会手动将其添加到请求中。

标签: javascript jquery html form-data


【解决方案1】:

因为对FormData的构造函数的调用不知道它是由单击提交按钮触发的(更不用说它是哪个提交按钮了),并且因为您只希望使用 em> 提交按钮的值包括在内,提交按钮不包括在发布的数据中。您可以使用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>

【讨论】:

  • 哦,是的,因为FormData 构造函数不知道我按下了哪个按钮:D
  • 隐藏的输入需要根据我点击的按钮动态填充正确的值,但我想现在这是一项不同的任务。
  • 实际上在我的情况下这是最好的方法,因为点击处理程序实际上是一个ajaxSubmitForm 在我的应用程序中的所有表单中通用的函数,但对于这个例子是:)
【解决方案2】:

正如您已经说过的,FormData 无法知道按钮的名称。但是当你抓到一个表单提交时,你可以通过submitter property on the event获取名称:

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
})

【讨论】:

  • 请注意,截至 2021 年 4 月,Safari(桌面版或移动版)不支持 submitter,如果您需要支持所有主流浏览器,这将是一个糟糕的选择。
  • 感谢您提供此信息,我不知道。您有什么建议我们可以改用吗?
  • 我没有。我一直在努力寻找解决我遇到的问题的方法,并且还认为这是一个很好的解决方案,直到我在 Safari 中进行测试:(
  • 一个补丁已根据bugs.webkit.org/show_bug.cgi?id=229660 登陆,但还没有在 safari 中。
【解决方案3】:

如果我在 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 中都获得了所需的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 2020-03-25
    • 1970-01-01
    • 2011-04-29
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多