Mon 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",
}
J'ai essayé de poster mon formulaire en utilisant fetch api, et le corps qu'il envoie ressemble à ceci:
-----------------------------114782935826962
Content-Disposition: form-data; name="email"
[email protected]
-----------------------------114782935826962
Content-Disposition: form-data; name="password"
pw
-----------------------------114782935826962--
(Je ne sais pas pourquoi le nombre dans la limite est changé chaque fois qu'il envoie ...)
Je voudrais qu'il envoie les données avec "Content-Type": "application/x-www-form-urlencoded", que dois-je faire? Ou, si je dois y faire face, comment décoder les données de mon contrôleur?
Pour qui répondre à ma question, je sais que je peux le faire avec:
fetch("api/xxx", {
body: "[email protected]&password=pw",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
method: "post",
}
Ce que je veux, c'est quelque chose comme $ ("# form"). Serialize () dans jQuery (sans utiliser jQuery) ou la manière de décoder les données mulitpart/form dans le contrôleur. Merci pour vos réponses cependant.
Pour citer MDN sur FormData
(souligné par moi):
L’interface
FormData
permet de construire facilement un ensemble de paires clé/valeur représentant les champs de formulaire et leurs valeurs, qui peuvent ensuite être facilement envoyées à l’aide de la méthodeXMLHttpRequest.send()
. Il utilise le même format qu'un formulaire utiliserait si le type de codage était défini sur _"multipart/form-data"
_.
Ainsi, lorsque vous utilisez FormData
, vous vous verrouillez dans _multipart/form-data
_. Il n'y a aucun moyen d'envoyer un objet FormData
en tant que corps et de ne pas envoyer des données au format _multipart/form-data
_.
Si vous souhaitez envoyer les données en tant que _application/x-www-form-urlencoded
_, vous devrez soit spécifier le corps en tant que chaîne codée par une URL, soit transmettre un objet URLSearchParams
. Ce dernier ne peut malheureusement pas être directement initialisé à partir d'un élément form
. Si vous ne voulez pas parcourir vous-même les éléments de formulaire (ce que vous pouviez faire avec HTMLFormElement.elements
), vous pouvez également créer un objet URLSearchParams
à partir d'un objet 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(…);
_
Notez qu'il n'est pas nécessaire de spécifier vous-même un en-tête _Content-Type
_.
Comme indiqué par monk-time dans les commentaires, vous pouvez également créer URLSearchParams
et transmettre directement l'objet FormData
au lieu d'ajouter les valeurs dans une boucle:
_const data = new URLSearchParams(new FormData(formElement));
_
Cela a toujours un support expérimental dans les navigateurs, alors assurez-vous de le tester correctement avant de l’utiliser.
Client
Ne définissez pas l'en-tête content-type.
// Build formData object.
let formData = new FormData();
formData.append('name', 'John');
formData.append('password', 'John123');
fetch("api/SampleData",
{
body: formData,
method: "post"
});
Serveur
Utilisez l'attribut FromForm
pour spécifier que la source de liaison est une donnée de formulaire.
[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; }
}
Vous pouvez définir body
sur une instance de URLSearchParams
avec une chaîne de requête passée en argument
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>