Как отправить объект 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));

Что я делаю не так?

kstratis
источник
1
Взгляните на API jQuery $.ajaxи serializeв нем.
Рори МакКроссан 05
1
Обязательно ли это должен быть объект JSON? Какую структуру должен иметь объект?
Энтони Грист
1
@AnthonyGrist Да, это должен быть JSON, потому что он адресован службе ReST.
kstratis 05
4
Что значит «не работает»? Помните, мы не видим ваш экран.
Dour High Arch
2
@ Konos5 - REST не имеет ничего общего с JSON. Это не требует, чтобы данные были в каком-то определенном формате.
Дэниэлм 01

Ответы:

136

Получить полные данные формы в виде массива и преобразовать их в json.

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

Вы можете использовать его позже в ajax. Или если вы не используете ajax; поместите его в скрытое текстовое поле и передайте на сервер. Если эти данные передаются в виде строки json через данные обычной формы, вам необходимо декодировать их с помощью json_decode . Затем вы получите все данные в виде массива.

$.ajax({
  type: "POST",
  url: "serverUrl",
  data: formData,
  success: function(){},
  dataType: "json",
  contentType : "application/json"
});
SachinGutte
источник
4
Вы отметили вопрос с помощью jQuery. Так ты им пользуешься? с $.ajaxего очень легко передать эти данные.
SachinGutte 05
51

HTML не позволяет создавать JSON из данных формы.

Если вы действительно хотите обрабатывать это от клиента, вам придется прибегнуть к использованию JavaScript, чтобы:

  1. собирать данные из формы через DOM
  2. организовать его в объект или массив
  3. сгенерировать JSON с помощью JSON.stringify
  4. POST с помощью XMLHttpRequest

Вам, вероятно, будет лучше придерживаться application/x-www-form-urlencodedданных и обрабатывать их на сервере, а не в JSON. В вашей форме нет сложной иерархии, которая выиграла бы от структуры данных JSON.


Обновление в ответ на серьезную переписывание вопроса…

  • В вашем JS нет readystatechange обработчика, поэтому вы ничего не делаете с ответом
  • Вы запускаете JS при нажатии кнопки отправки, не отменяя поведения по умолчанию. Браузер отправит форму (обычным способом), как только функция JS будет завершена.
Quentin
источник
1
Хорошо, как мне это исправить?
kstratis
1
@Quentin: В моем случае мне нужен междоменный POST без контроля домена.
user2284570
1
@ user2284570 - Если у вас есть новый вопрос, задайте его.
Квентин,
1
Есть предложение добавить enctype='application/json'в определение формы для создания данных JSON w3.org/TR/html-json-forms
EkriirkE
4
@EkriirkE - Вы читали эту страницу? Там написано в массивной коробке с черно-желтой полосой опасности по периметру. Осторожно. Эта спецификация больше не находится в активной поддержке, и рабочая группа HTML не намеревается поддерживать ее в дальнейшем.
Quentin
3

ваш код в порядке, но никогда не выполняется, из-за кнопки отправки [type = "submit"] просто замените его на type = button

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

внутри вашего скрипта; форма не заявлена.

let form = document.forms[0];
xhr.open(form.method, form.action, true);
tdjprog
источник
Именно type = "button" очень важен, если не использовать, то перенаправляет с параметрами url.
Rohit Parte
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"
 }
}
orafaelreis
источник
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>
Хасан А Юсеф
источник