Как отправить данные формы с помощью 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"
[email protected]
-----------------------------114782935826962
Content-Disposition: form-data; name="password"
pw
-----------------------------114782935826962--
(Я не знаю, почему число в границе меняется каждый раз, когда он отправляет...)
Я бы хотел, чтобы он отправлял данные с помощью "Content-Type": "application/x-www-form-urlencoded", что мне делать? Или, если мне просто нужно иметь дело с этим, как мне декодировать данные в моем контроллере?
Чтобы ответить на мой вопрос, я знаю, что могу это сделать:
fetch("api/xxx", {
body: "[email protected]&password=pw",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
method: "post",
}
Я хочу что-то вроде $ ("# form"). Serialize() в jQuery (без использования jQuery) или способ декодирования mulitpart/form-data в контроллере. Спасибо за ваши ответы.
Ответы
Ответ 1
Чтобы FormData
MDN на FormData
(выделение мое):
Интерфейс FormData
предоставляет возможность легко построить набор пар ключ/значение, представляющих поля формы и их значения, которые затем могут быть легко отправлены с использованием метода XMLHttpRequest.send()
. Он использует тот же формат, который форма использовала бы, если для типа кодировки были установлены "multipart/form-data"
.
Поэтому при использовании FormData
вы блокируете себя в multipart/form-data
. FormData
отправить объект FormData
в качестве тела и не отправлять данные в формате multipart/form-data
.
Если вы хотите отправить данные в виде application/x-www-form-urlencoded
вам нужно будет указать тело как строку с кодировкой URL-адреса или передать объект URLSearchParams
. Последние, к сожалению, не могут быть непосредственно инициализированы из элемента form
. Если вы не хотите выполнять итерацию через свои элементы формы (что вы можете сделать с помощью HTMLFormElement.elements
), вы также можете создать объект URLSearchParams
из объекта FormData
:
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
напрямую, а не FormData
значения в цикле:
const data = new URLSearchParams(new FormData(formElement));
Тем не менее, в браузерах все еще есть экспериментальная поддержка, поэтому прежде чем использовать его, обязательно проверьте это правильно.
Ответ 2
клиент
Не устанавливайте заголовок содержимого.
// 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; }
}
Ответ 3
Вы можете установить body
в экземпляр URLSearchParams
с строкой запроса, переданной как аргумент
fetch("/path/to/server", {
method:"POST"
, body:new URLSearchParams("[email protected]&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="[email protected]">
<input name="password" value="pw">
<input type="submit">
</form>