【问题标题】:How to send a JSON object using html form data如何使用 html 表单数据发送 JSON 对象
【发布时间】:2014-04-07 08:27:19
【问题描述】:

所以我得到了这个 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));

我做错了什么?

【问题讨论】:

  • 看看 jQuery API 中的 $.ajaxserialize
  • 它必须是 JSON 对象吗?对象应该有什么结构?
  • @AnthonyGrist 是的,它必须是 JSON,因为它是针对 ReST 服务的。
  • “似乎不起作用”是什么意思?请记住,我们看不到您的屏幕。
  • @Konos5 - REST 与 JSON 无关。它不要求数据采用任何特定格式。

标签: javascript jquery html json forms


【解决方案1】:

使用 FormData API

  1. 使用 FormData API formData= new FormData(form) 捕获表单数据
  2. 使用JSON.stringify(Object.fromEntries(formData))将其转换为JSON
  3. 将此经过标记的 json 作为 ajax 有效负载发送
var form = document.getElementById('myForm');
form.onsubmit = function(event){
        var xhr = new XMLHttpRequest();
        var formData = new FormData(form);
        //open the request
        xhr.open('POST','http://localhost:7000/tests/v1.0/form')
        xhr.setRequestHeader("Content-Type", "application/json");

        //send the form data
        xhr.send(JSON.stringify(Object.fromEntries(formData)));

        xhr.onreadystatechange = function() {
            if (xhr.readyState == XMLHttpRequest.DONE) {
                form.reset(); //reset form after AJAX success or do something else
            }
        }
        //Fail the onsubmit to avoid page refresh.
        return false; 
    }

参考:https://metamug.com/article/html5/ajax-form-submit.html

【讨论】:

    【解决方案2】:

    微库field-assist 正是这样做的:collectValues(formElement) 将从输入字段返回一个规范化 json(这也意味着,复选框作为布尔值,选择作为字符串等)。

    【讨论】:

      【解决方案3】:

      我找到了一种仅使用 HTML 表单传递 JSON 消息的方法。

      此示例适用于 GraphQL,但它适用于任何需要 JSON 消息的端点。

      GrapqhQL 默认需要一个名为操作的参数,您可以在其中添加 JSON 格式的查询或突变。在这种特定情况下,我正在调用此查询,该查询请求获取 allUsers 并返回每个用户的 userId。

      { 
       allUsers 
        { 
        userId 
        }
      }
      

      我正在使用文本输入来演示如何使用它,但您可以将其更改为隐藏输入以向用户隐藏查询。

      <html>
      <body>
          <form method="post" action="http://localhost:8080/graphql">
              <input type="text" name="operations" value="{&quot;query&quot;: &quot;{ allUsers { userId } }&quot;, "variables":  {}}"/>
              <input type="submit" />
          </form>
      </body>
      </html>
      

      为了使这种动态化,您需要 JS 在提交表单之前将文本字段的值传输到查询字符串。无论如何,我发现这种方法非常有趣。希望对您有所帮助。

      【讨论】:

      • 这不会发布 json 而是带有 json 值的单一表单输入 - 这是一个很大的区别
      【解决方案4】:

      你可以试试这样的:

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

      【讨论】:

        【解决方案5】:

        我来晚了,但我需要对那些需要对象的人说,只使用 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"
         }
        }
        

        【讨论】:

        • 这个我没有测试过,但这似乎也是一个不错的解决方案。
        • 这不会发布 json 而是纯格式数据。框架 conversta 为您服务。我很惊讶这会得到如此多的支持。
        【解决方案6】:

        您的代码很好,但从未执行过,提交按钮的原因 [type="submit"] 只需将其替换为 type=button

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

        在你的脚本里面; form 未声明。

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

        【讨论】:

        • Exactly type="button" 很重要,如果不使用则使用url参数重定向。
        【解决方案7】:

        以数组的形式获取完整的表单数据并将其 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"
        });
        

        【讨论】:

        • 你已经用 jQuery 标记了问题。那你在用吗?使用$.ajax,传递这些数据真的很容易。
        【解决方案8】:

        HTML 无法从表单数据生成 JSON。

        如果您真的想从客户端处理它,那么您将不得不求助于使用 JavaScript 来:

        1. 通过 DOM 从表单中收集数据
        2. 在对象或数组中组织它
        3. 使用JSON.stringify 生成 JSON
        4. XMLHttpRequest发布它

        您最好坚持使用application/x-www-form-urlencoded 数据并在服务器上处理它而不是 JSON。您的表单没有任何可以从 JSON 数据结构中受益的复杂层次结构。


        针对问题的重大改写进行更新……

        • 你的 JS 没有 readystatechange 处理程序,所以你对响应什么也不做
        • 您在点击提交按钮时触发 JS,而不取消默认行为。 JS功能完成后,浏览器会立即提交表单(以常规方式)。

        【讨论】:

        • 好的,我该如何解决这个问题?
        • @Quentin :在我的情况下,我需要没有域控制的跨域 POST。
        • @user2284570 — 如果您有新问题,那么ask 一个。
        • 有提议在表单定义中添加enctype='application/json'创建JSON数据w3.org/TR/html-json-forms
        • @EkriirkE — 你读过那个页面吗?它说,在一个巨大的盒子里,周围有黑色和黄色的危险条纹小心。该规范不再处于积极维护中,HTML 工作组也不打算进一步维护它。
        猜你喜欢
        • 1970-01-01
        • 2017-03-12
        • 1970-01-01
        • 1970-01-01
        • 2020-07-12
        • 2019-03-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多