如何使用 fetch api 发布表单数据? [英] How do I post form data with fetch api?

查看:72
本文介绍了如何使用 fetch api 发布表单数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码:

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 发布我的表单,它发送的正文如下:

I tried to post my form using fetch api, and the body it sends is like:

-----------------------------114782935826962
Content-Disposition: form-data; name="email"

test@example.com
-----------------------------114782935826962
Content-Disposition: form-data; name="password"

pw
-----------------------------114782935826962--

(不知道为什么每次发送的时候边界里面的数字都变了...)

(I don't know why the number in boundary is changed every time it sends...)

我希望它发送带有Content-Type"的数据:application/x-www-form-urlencoded",我该怎么办?或者如果我只需要处理它,我如何解码控制器中的数据?

I would like it to send the data with "Content-Type": "application/x-www-form-urlencoded", what should I do? Or if I just have to deal with it, how do I decode the data in my controller?

向谁回答我的问题,我知道我可以做到:

To whom answer my question, I know I can do it with:

fetch("api/xxx", {
    body: "email=test@example.com&password=pw",
    headers: {
        "Content-Type": "application/x-www-form-urlencoded",
    },
    method: "post",
}

我想要的是 jQuery 中的 $("#form").serialize() (不使用 jQuery)或解码控制器中的 mulitpart/form-data 的方法.不过还是谢谢你的回答.

What I want is something like $("#form").serialize() in jQuery (w/o using jQuery) or the way to decode mulitpart/form-data in controller. Thanks for your answers though.

推荐答案

引用 FormData 上的 MDN(强调我的):

To quote MDN on FormData (emphasis mine):

FormData 接口提供了一种轻松构建一组表示表单字段及其值的键/值对的方法,然后可以使用 XMLHttpRequest.send() 方法.如果编码类型设置为"multipart/form-data",它使用的格式与表单将使用的格式相同.

The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to "multipart/form-data".

因此,当使用 FormData 时,您将自己锁定在 multipart/form-data 中.无法将 FormData 对象作为正文发送,并且multipart/form-data 格式发送数据.

So when using FormData you are locking yourself into multipart/form-data. There is no way to send a FormData object as the body and not sending data in the multipart/form-data format.

如果您想将数据作为 application/x-www-form-urlencoded 发送,您必须将正文指定为 URL 编码的字符串,或者传递一个 URLSearchParams 对象.不幸的是,后者不能直接从 form 元素初始化.如果您不想自己遍历表单元素(您可以使用HTMLFormElement.elements),您还可以从 FormData 创建一个 URLSearchParams 对象> 对象:

If you want to send the data as application/x-www-form-urlencoded you will either have to specify the body as an URL-encoded string, or pass a URLSearchParams object. The latter unfortunately cannot be directly initialized from a form element. If you don’t want to iterate through your form elements yourself (which you could do using HTMLFormElement.elements), you could also create a URLSearchParams object from a FormData object:

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 标头.

Note that you do not need to specify a Content-Type header yourself.

正如评论中的 monk-time 所指出的,您还可以创建 URLSearchParams 并直接传递 FormData 对象,而不是在循环中附加值:

As noted by monk-time in the comments, you can also create URLSearchParams and pass the FormData object directly, instead of appending the values in a loop:

const data = new URLSearchParams(new FormData(formElement));

尽管如此,这在浏览器中仍然有一些实验性支持,因此请确保在使用前对其进行正确测试.

This still has some experimental support in browsers though, so make sure to test this properly before you use it.

这篇关于如何使用 fetch api 发布表单数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆