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

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

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

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

(我不知道为什么每次发送时边界中的数字都会改变……)

我希望它使用“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",
}

我想要的是 jQuery 中的 $(“#form”).serialize() (不使用 jQuery)或在控制器中解码 mulitpart/form-data 的方式。不过感谢您的回答。

原文由 Zack 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.7k
2 个回答

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

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

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

如果要将数据作为 application/x-www-form-urlencoded 发送,则必须将正文指定为 URL 编码字符串,或传递 URLSearchParams 对象。遗憾的是后者不能直接从 form 元素初始化。如果您不想自己遍历表单元素( 可以 使用 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 标头。


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

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

不过,这在浏览器中仍有一些实验性支持,因此请确保在使用之前对其进行正确测试。

原文由 poke 发布,翻译遵循 CC BY-SA 3.0 许可协议

客户

不要设置内容类型标头。

 // Build formData object.
let formData = new FormData();
formData.append('name', 'John');
formData.append('password', 'John123');

fetch("api/SampleData",
    {
        body: formData,
        method: "post"
    });

服务器

使用 FromForm 属性指定绑定源是表单数据。

 [Route("api/[controller]")]
public class SampleDataController : Controller
{
    [HttpPost]
    public IActionResult Create([FromForm]UserDto dto)
    {
        return Ok();
    }
}

public class UserDto
{
    public string Name { get; set; }
    public string Password { get; set; }
}

原文由 regnauld 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题