FormData 不包含按钮的值
FormData doesn't include value of buttons
考虑以下片段:
$('#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包含按钮提供的数据?
因为调用 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>
如您所述,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
})
如果我在 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 中都获得了所需的行为。
考虑以下片段:
$('#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包含按钮提供的数据?
因为调用 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>
如您所述,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
})
如果我在 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 中都获得了所需的行为。