How do I post form data with fetch api?

穿精又带淫゛_ 提交于 2019-11-26 02:35:40

问题


My code:

fetch(\"api/xxx\", {
    body: new FormData(document.getElementById(\"form\")),
    headers: {
        \"Content-Type\": \"application/x-www-form-urlencoded\",
        // \"Content-Type\": \"multipart/form-data\",
    },
    method: \"post\",
}

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

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\",
}

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.


回答1:


To quote MDN on FormData (emphasis mine):

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".

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.

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(…);

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


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.




回答2:


Client

Do not set the content-type header.

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

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

Server

Use the FromForm attribute to specify that binding source is form data.

[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; }
}



回答3:


You can set body to an instance of URLSearchParams with query string passed as argument

fetch("/path/to/server", {
  method:"POST"
, body:new URLSearchParams("email=test@example.com&password=pw")
})

document.forms[0].onsubmit = async(e) => {
  e.preventDefault();
  const params = new URLSearchParams([...new FormData(e.target).entries()]);
  // fetch("/path/to/server", {method:"POST", body:params})
  const response = await new Response(params).text();
  console.log(response);
}
<form>
  <input name="email" value="test@example.com">
  <input name="password" value="pw">
  <input type="submit">
</form>


来源:https://stackoverflow.com/questions/46640024/how-do-i-post-form-data-with-fetch-api

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!