Jak wysłać obiekt JSON za pomocą danych formularza html

129

Mam więc ten formularz 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>

Jaki byłby najłatwiejszy sposób na przesłanie danych tego formularza jako obiektu JSON na mój serwer, gdy użytkownik kliknie przycisk Prześlij?

AKTUALIZACJA: posunąłem się aż do tego, ale wydaje się, że nie działa:

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

Co ja robię źle?

kstratis
źródło
1
Spójrz na jQuery API $.ajaxi serializew nim.
Rory McCrossan,
1
Czy to absolutnie musi być obiektem JSON? Jaką strukturę powinien mieć obiekt?
Anthony Grist
1
@AnthonyGrist Tak, to musi być JSON, ponieważ jest adresowany do usługi ReST.
kstratis
4
Co oznacza „nie działa”? Pamiętaj, że nie widzimy Twojego ekranu.
Dour High Arch
2
@ Konos5 - REST nie ma nic wspólnego z JSON. Nie wymaga, aby dane miały określony format.
danielm

Odpowiedzi:

136

Uzyskaj pełne dane formularza jako tablicę i json zdefiniuj je.

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

Możesz go później użyć w Ajax. Lub jeśli nie używasz Ajax; umieść go w ukrytym obszarze tekstowym i przekaż do serwera. Jeśli te dane są przekazywane jako ciąg json za pośrednictwem normalnych danych formularza, musisz je zdekodować za pomocą json_decode . Otrzymasz wtedy wszystkie dane w tablicy.

$.ajax({
  type: "POST",
  url: "serverUrl",
  data: formData,
  success: function(){},
  dataType: "json",
  contentType : "application/json"
});
SachinGutte
źródło
4
Oznaczyłeś pytanie za pomocą jQuery. Więc używasz go? dzięki $.ajaxtemu bardzo łatwo jest przekazać te dane.
SachinGutte
51

HTML nie zapewnia możliwości generowania JSON z danych formularza.

Jeśli naprawdę chcesz załatwić to od klienta, musisz skorzystać z JavaScript, aby:

  1. zbierz swoje dane z formularza przez DOM
  2. zorganizować go w obiekcie lub tablicy
  3. wygeneruj JSON za pomocą JSON.stringify
  4. POST to za pomocą XMLHttpRequest

Prawdopodobnie lepiej byłoby trzymać się application/x-www-form-urlencodeddanych i przetwarzać je na serwerze zamiast JSON. Twój formularz nie ma żadnej skomplikowanej hierarchii, która przyniosłaby korzyści w postaci struktury danych JSON.


Aktualizacja w odpowiedzi na poważne przepisanie pytania…

  • Twój JS nie ma readystatechangeobsługi, więc nic nie robisz z odpowiedzią
  • Uruchamiasz JS po kliknięciu przycisku przesyłania bez anulowania domyślnego zachowania. Przeglądarka prześle formularz (w zwykły sposób), gdy tylko funkcja JS zostanie zakończona.
Quentin
źródło
1
OK, więc jak to naprawić?
kstratis
1
@Quentin: W moim przypadku potrzebuję międzydomenowego POST bez kontroli domeny.
user2284570
1
@ user2284570 - Jeśli masz nowe pytanie, zadaj je.
Quentin
1
Jest propozycja dodania enctype='application/json'do definicji formularza w celu utworzenia danych JSON w3.org/TR/html-json-forms
EkriirkE
4
@EkriirkE - Czy czytałeś tę stronę? Mówi, w ogromnym pudełku z czarno-żółtym paskiem ostrzegawczym wokół niego . Uwaga. Ta specyfikacja nie podlega już aktywnej konserwacji, a Grupa Robocza HTML nie zamierza dalej jej utrzymywać.
Quentin
3

Twój kod jest w porządku, ale nigdy nie jest wykonywany, przyczyna wysłania przycisku [type = "submit"] po prostu zamień go na type = button

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

wewnątrz twojego skryptu; formularz nie jest zadeklarowany.

let form = document.forms[0];
xhr.open(form.method, form.action, true);
tdjprog
źródło
Dokładnie type = "button" jest bardzo ważne, jeśli nie, to przekierowuje z parametrami adresu URL.
Rohit Parte
1

Spóźniłem się, ale muszę powiedzieć, że dla tych, którzy potrzebują obiektu, używając tylko html, jest na to sposób. W niektórych frameworkach po stronie serwera, takich jak PHP, możesz napisać następujący kod:

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

Musimy więc ustawić nazwę wejścia tak, jak object[property]dla otrzymanego obiektu. W powyższym przykładzie otrzymaliśmy dane z następującym kodem JSON:

{
"name": {
  "first": "some data",
  "last": "some data"
 }
}
orafaelreis
źródło
0

Możesz spróbować czegoś takiego:

<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
źródło