Comment envoyer un objet JSON à l'aide de données de formulaire HTML

129

J'ai donc ce formulaire HTML:

<html>
<head><title>test</title></head>
<body>
    <form action="myurl" method="POST" name="myForm">
        <p><label for="first_name">First Name:</label>
        <input type="text" name="first_name" id="fname"></p>

        <p><label for="last_name">Last Name:</label>
        <input type="text" name="last_name" id="lname"></p>

        <input value="Submit" type="submit" onclick="submitform()">
    </form>
</body>
</html>

Quel serait le moyen le plus simple d'envoyer les données de ce formulaire en tant qu'objet JSON à mon serveur lorsqu'un utilisateur clique sur Soumettre?

MISE À JOUR: Je suis allé aussi loin que cela mais cela ne semble pas fonctionner:

<script type="text/javascript">
    function submitform(){
        alert("Sending Json");
        var xhr = new XMLHttpRequest();
        xhr.open(form.method, form.action, true);
        xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
        var j = {
            "first_name":"binchen",
            "last_name":"heris",
        };
        xhr.send(JSON.stringify(j));

Qu'est-ce que je fais mal?

kstratis
la source
1
Jetez un œil à $.ajaxet serializedans l'API jQuery.
Rory McCrossan
1
Doit-il absolument être un objet JSON? Quelle structure doit avoir l'objet?
Anthony Grist
1
@AnthonyGrist Oui, il doit s'agir d'un JSON car il est adressé à un service ReST.
kstratis
4
Que signifie «ne semble pas fonctionner»? N'oubliez pas que nous ne pouvons pas voir votre écran.
Dour High Arch
2
@ Konos5 - REST n'a rien à voir avec JSON. Il n'est pas nécessaire que les données soient dans un format particulier.
danielm

Réponses:

136

Obtenez des données de formulaire complètes sous forme de tableau et json stringify.

var formData = JSON.stringify($("#myForm").serializeArray());

Vous pourrez l'utiliser plus tard dans ajax. Ou si vous n'utilisez pas ajax; placez-le dans une zone de texte cachée et passez au serveur. Si ces données sont passées sous forme de chaîne json via des données de forme normale, vous devez les décoder à l'aide de json_decode . Vous obtiendrez alors toutes les données dans un tableau.

$.ajax({
  type: "POST",
  url: "serverUrl",
  data: formData,
  success: function(){},
  dataType: "json",
  contentType : "application/json"
});
SachinGutte
la source
4
Vous avez tagué la question avec jQuery. Alors l'utilisez vous? avec $.ajaxil est vraiment facile de transmettre ces données.
SachinGutte
51

HTML ne fournit aucun moyen de générer du JSON à partir de données de formulaire.

Si vous voulez vraiment le gérer à partir du client, vous devrez alors recourir à l'utilisation de JavaScript pour:

  1. recueillir vos données à partir du formulaire via DOM
  2. l'organiser dans un objet ou un tableau
  3. générer JSON avec JSON.stringify
  4. POSTER avec XMLHttpRequest

Vous feriez probablement mieux de vous en tenir aux application/x-www-form-urlencodeddonnées et de les traiter sur le serveur au lieu de JSON. Votre formulaire n'a pas de hiérarchie compliquée qui bénéficierait d'une structure de données JSON.


Mise à jour en réponse à une réécriture majeure de la question…

  • Votre JS n'a pas de readystatechangegestionnaire, vous ne faites donc rien avec la réponse
  • Vous déclenchez le JS lorsque vous cliquez sur le bouton Soumettre sans annuler le comportement par défaut. Le navigateur soumettra le formulaire (de la manière habituelle) dès que la fonction JS sera terminée.
Quentin
la source
1
OK, alors comment résoudre ce problème?
kstratis
1
@Quentin: Dans mon cas, j'ai besoin d'un POST interdomaine sans contrôle de domaine.
user2284570
1
@ user2284570 - Si vous avez une nouvelle question, posez-en une.
Quentin
1
Il existe une proposition d'ajout enctype='application/json'à la définition de formulaire pour créer des données JSON w3.org/TR/html-json-forms
EkriirkE
4
@EkriirkE - Avez-vous lu cette page? Il dit, dans une boîte massive avec une bande de danger noire et jaune autour d'elle.Méfiez- vous. Cette spécification n'est plus en maintenance active et le groupe de travail HTML n'a pas l'intention de la maintenir davantage.
Quentin
3

votre code est correct mais jamais exécuté, cause du bouton d'envoi [type = "submit"] il suffit de le remplacer par type = bouton

<input value="Submit" type="button" onclick="submitform()">

à l'intérieur de votre script; la forme n'est pas déclarée.

let form = document.forms[0];
xhr.open(form.method, form.action, true);
tdjprog
la source
Exactement type = "button" est très important, sinon utilisez-le alors il redirige avec des paramètres d'url.
Rohit Parte
1

Je suis en retard mais je dois dire que pour ceux qui ont besoin d'un objet, n'utilisant que du HTML, il y a un moyen. Dans certains frameworks côté serveur comme PHP, vous pouvez écrire le code suivant:

<form action="myurl" method="POST" name="myForm">
        <p><label for="first_name">First Name:</label>
        <input type="text" name="name[first]" id="fname"></p>

        <p><label for="last_name">Last Name:</label>
        <input type="text" name="name[last]" id="lname"></p>

        <input value="Submit" type="submit">
    </form>

Donc, nous devons configurer le nom de l'entrée comme object[property]pour obtenir un objet. Dans l'exemple ci-dessus, nous avons obtenu une donnée avec le JSON suivant:

{
"name": {
  "first": "some data",
  "last": "some data"
 }
}
orafaelreis
la source
0

Vous pouvez essayer quelque chose comme:

<html>
<head>
    <title>test</title>
</head>

<body>
    <form id="formElem">
        <input type="text" name="firstname" value="Karam">
        <input type="text" name="lastname" value="Yousef">
        <input type="submit">
    </form>
    <div id="decoded"></div>
    <button id="encode">Encode</button>
    <div id="encoded"></div>
</body>
<script>
    encode.onclick = async (e) => {
        let response = await fetch('http://localhost:8482/encode', {
                method: 'GET',
                headers: {
                    'Content-Type': 'application/json',
                },
        })

        let text = await response.text(); // read response body as text
        data = JSON.parse(text);
        document.querySelector("#encoded").innerHTML = text;
      //  document.querySelector("#encoded").innerHTML = `First name = ${data.firstname} <br/> 
      //                                                  Last name = ${data.lastname} <br/>
      //                                                  Age    = ${data.age}`
    };

    formElem.onsubmit = async (e) => {
      e.preventDefault();
      var form = document.querySelector("#formElem");
     // var form = document.forms[0];

        data = {
          firstname : form.querySelector('input[name="firstname"]').value,
          lastname : form.querySelector('input[name="lastname"]').value,
          age : 5
        }

        let response = await fetch('http://localhost:8482/decode', {
                method: 'POST', // or 'PUT'
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(data),
        })

        let text = await response.text(); // read response body as text
        document.querySelector("#decoded").innerHTML = text;
    };
</script>
</html>
Hasan A Yousef
la source