我的代码:
fetch("api/xxx", {
body: new FormData(document.getElementById("form")),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
// "Content-Type": "multipart/form-data",
},
method: "post",
}
我尝试使用fetch api发布我的表单,它发送的正文是这样的:
-----------------------------114782935826962
Content-Disposition: form-data; name="email"
test@example.com
-----------------------------114782935826962
Content-Disposition: form-data; name="password"
pw
-----------------------------114782935826962--
(我不知道为什么每次发送的时候boundary里的数字都会变…)
我想用“Content-Type”:“application/x-www-form-urlencoded”发送数据,我该怎么做?或者如果我必须处理它,我如何解码控制器中的数据?
请回答我的问题,我知道我能做到:
fetch("api/xxx", {
body: "email=test@example.com&password=pw",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
method: "post",
}
我想要的是像$(“#form”).serialize()在jQuery (w/o使用jQuery)或解码控制器中的多部分/表单数据的方法。谢谢你的回答。
引用FormData上的MDN(重点是我的):
FormData接口提供了一种方法,可以轻松地构造一组表示表单字段及其值的键/值对,然后可以使用XMLHttpRequest.send()方法轻松地发送这些字段。它使用与编码类型设置为“multipart/form-data”的表单相同的格式。
所以当你使用FormData时,你就把自己锁在了multipart/form-data中。没有办法将FormData对象作为主体发送,而不以multipart/form-data格式发送数据。
如果你想要以application/x-www-form-urlencoded的形式发送数据,你必须将主体指定为url编码的字符串,或者传递一个URLSearchParams对象。不幸的是,后者不能直接从表单元素初始化。如果你不想自己遍历你的表单元素(你可以使用HTMLFormElement.elements),你也可以从FormData对象创建一个URLSearchParams对象:
const data = new URLSearchParams();
for (const pair of new FormData(formElement)) {
data.append(pair[0], pair[1]);
}
fetch(url, {
method: 'post',
body: data,
})
.then(…);
注意,您不需要自己指定Content-Type标头。
正如monk-time在注释中所指出的,你也可以创建URLSearchParams并直接传递FormData对象,而不是在循环中追加值:
const data = new URLSearchParams(new FormData(formElement));
不过,在浏览器中仍然有一些实验性的支持,所以在使用它之前一定要进行适当的测试。
引用FormData上的MDN(重点是我的):
FormData接口提供了一种方法,可以轻松地构造一组表示表单字段及其值的键/值对,然后可以使用XMLHttpRequest.send()方法轻松地发送这些字段。它使用与编码类型设置为“multipart/form-data”的表单相同的格式。
所以当你使用FormData时,你就把自己锁在了multipart/form-data中。没有办法将FormData对象作为主体发送,而不以multipart/form-data格式发送数据。
如果你想要以application/x-www-form-urlencoded的形式发送数据,你必须将主体指定为url编码的字符串,或者传递一个URLSearchParams对象。不幸的是,后者不能直接从表单元素初始化。如果你不想自己遍历你的表单元素(你可以使用HTMLFormElement.elements),你也可以从FormData对象创建一个URLSearchParams对象:
const data = new URLSearchParams();
for (const pair of new FormData(formElement)) {
data.append(pair[0], pair[1]);
}
fetch(url, {
method: 'post',
body: data,
})
.then(…);
注意,您不需要自己指定Content-Type标头。
正如monk-time在注释中所指出的,你也可以创建URLSearchParams并直接传递FormData对象,而不是在循环中追加值:
const data = new URLSearchParams(new FormData(formElement));
不过,在浏览器中仍然有一些实验性的支持,所以在使用它之前一定要进行适当的测试。