Як надіслати об’єкт JSON за допомогою даних форми HTML


129

Отож у мене така форма 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>

Який був би найпростіший спосіб надіслати дані цієї форми як об’єкт JSON на мій сервер, коли користувач натискає кнопку "Надіслати"?

ОНОВЛЕННЯ: Я зайшов до цього, але це, здається, не працює:

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

Що я роблю неправильно?


1
Погляньте $.ajaxі serializeв API JQuery.
Рорі Маккросан

1
Чи абсолютно це має бути об'єктом JSON? Яку структуру повинен мати об’єкт?
Ентоні Гріст

1
@AnthonyGrist Так, це повинен бути JSON, оскільки він адресований службі ReST.
kstratis

4
Що означає "схоже, що не працює"? Пам'ятайте, ми не можемо побачити ваш екран.
Арка високої арки

2
@ Konos5 - REST не має нічого спільного з JSON. Для цього не потрібно, щоб дані були у якомусь конкретному форматі.
danielm

Відповіді:


136

Отримайте повні дані форми у вигляді масиву та json впорядкуйте їх.

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

Ви можете використовувати його пізніше в аякс. Або якщо ви не використовуєте ajax; помістити його в приховану текстову область та передати на сервер. Якщо ці дані передаються у вигляді рядка json через дані звичайної форми, тоді вам доведеться розшифрувати їх за допомогою json_decode . Потім ви отримаєте всі дані в масиві.

$.ajax({
  type: "POST",
  url: "serverUrl",
  data: formData,
  success: function(){},
  dataType: "json",
  contentType : "application/json"
});

4
Ви позначили питання jQuery. Так ти це використовуєш? завдяки $.ajaxцьому передати ці дані дуже просто.
SachinGutte

51

HTML не дає можливості генерувати JSON з даних форми.

Якщо ви дійсно хочете обробляти це у клієнта, вам доведеться вдатися до використання JavaScript для:

  1. зібрати свої дані з форми через DOM
  2. впорядкуйте його в об'єкті або масиві
  3. генерувати JSON за допомогою JSON.stringify
  4. Розмістіть його за допомогою XMLHttpRequest

Можливо, вам буде краще дотримуватися application/x-www-form-urlencodedданих та обробляти їх на сервері замість JSON. У вашій формі немає складної ієрархії, яка б виграла від структури даних JSON.


Оновлення у відповідь на основне переписування питання ...

  • У вашого JS немає readystatechangeобробника, тому ви нічого не робите з відповіддю
  • Ви запускаєте JS, коли натискаєте кнопку подання, не скасовуючи поведінку за замовчуванням. Веб-браузер подасть форму (звичайним чином), як тільки функція JS буде виконана.

1
Гаразд, так як я можу це виправити?
кстратіс

1
@Quentin: У моєму випадку мені потрібен міждоменний POST без контролю домену.
користувач2284570

1
@ user2284570 - Якщо у вас є нове запитання, задайте його.
Квентін

1
Є пропозиція додати enctype='application/json'до визначення форми для створення даних JSON w3.org/TR/html-json-forms
EkriirkE

4
@EkriirkE - Ви читали цю сторінку? Кажуть, у масивній коробці з чорно-жовтою смугою небезпеки навколо неї Остерігайся. Ця специфікація більше не знаходиться в активному обслуговуванні, і робоча група HTML не має наміру підтримувати її далі.
Квентін

3

у вас код добре, але ніколи не виконується, причиною кнопки подання [type = "submit"] просто замініть його на type = button

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

всередині вашого сценарію; форма не задекларована.

let form = document.forms[0];
xhr.open(form.method, form.action, true);

Точно type = "button" дуже важливий, якщо не використовується, то він перенаправляє URL-адреси.
Рохіт

1

Я спізнююсь, але мені потрібно сказати, що для тих, кому потрібен об’єкт, використовуючи лише html, є спосіб. У деяких структурах на стороні сервера, таких як PHP, ви можете написати наступний код:

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

Отже, нам потрібно встановити ім'я вводу, як object[property]для отриманого об'єкта. У наведеному вище прикладі ми отримали дані з наступним JSON:

{
"name": {
  "first": "some data",
  "last": "some data"
 }
}

0

Ви можете спробувати щось на кшталт:

<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>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.