【问题标题】:form serialize javascript (no framework)表单序列化javascript(无框架)
【发布时间】:2012-07-24 13:27:42
【问题描述】:

想知道 javascript 中是否有没有 jquery 或任何允许我序列化表单并访问序列化版本的框架的函数?

【问题讨论】:

标签: javascript forms serialization


【解决方案1】:

这是纯 JavaScript 方法:

var form = document.querySelector('form');
var data = new FormData(form);
var req = new XMLHttpRequest();
req.send(data);

虽然它似乎只适用于 POST 请求。

https://developer.mozilla.org/en-US/docs/Web/API/FormData

【讨论】:

  • 注意,这会发送多部分,这与一些简单的 REST 服务(例如,feathers-mongoDB)效果不佳
  • 我认为你是对的,它只适用于 POST 请求。文档中并没有立即明确这一点。
  • 注意,您可能必须在 req.send(data); 之前使用 req.open("POST", "<your-url>"); 否则我在 Firefox 66 上遇到错误 InvalidStateError: XMLHttpRequest state must be OPENED.。它应该与其他请求一起使用,例如 PUT 是您将 POST 替换为 PUT。
  • 想一想:如何使用“GET”方法发送 FormData 对象?是的,FormData 仅适用于“POST”。
  • 仍然可以通过 GET 方法提交 frm。
【解决方案2】:

仅适用于现代浏览器

如果您的目标浏览器支持 URLSearchParams API (most recent browsers) 和 FormData(formElement) 构造函数 (most recent browsers),请使用:

new URLSearchParams(new FormData(formElement)).toString()

除了 IE 以外的所有地方

对于支持URLSearchParams 但不支持FormData(formElement) 构造函数的浏览器,请使用this FormData polyfill 和此代码(适用于除 IE 之外的任何地方):

new URLSearchParams(Array.from(new FormData(formElement))).toString()

示例

var form = document.querySelector('form');
var out = document.querySelector('output');

function updateResult() {
  try {
    out.textContent = new URLSearchParams(Array.from(new FormData(form)));
    out.className = '';
  } catch (e) {
    out.textContent = e;
    out.className = 'error';
  }
}

updateResult();
form.addEventListener('input', updateResult);
body { font-family: Arial, sans-serif; display: flex; flex-wrap: wrap; }
input[type="text"] { margin-left: 6px; max-width: 30px; }
label + label { margin-left: 10px; }
output { font-family: monospace; }
.error { color: #c00; }
div { margin-right: 30px; }
<!-- FormData polyfill for older browsers -->
<script src="https://unpkg.com/formdata-polyfill@3.0.17/formdata.min.js"></script>
<div>
  <h3>Form</h3>
  <form id="form">
    <label>x:<input type="text" name="x" value="1"></label>
    <label>y:<input type="text" name="y" value="2"></label>
    <label>
    z:
    <select name="z">
      <option value="a" selected>a</option>
      <option value="b" selected>b</option>
    </select>
  </label>
  </form>
</div>
<div>
  <h3>Query string</h3>
  <output for="form"></output>
</div>

兼容 IE 10

对于更旧的浏览器(例如 IE 10),使用FormData polyfill,必要时使用Array.from polyfill 和此代码:

Array.from(
  new FormData(formElement),
  function(e) { return e.map(encodeURIComponent).join('='); }
).join('&')

【讨论】:

  • 这里真的需要.toString()吗?
  • 如果你想要一个字符串而不是URLSearchParams,那么可以。如果您将字符串插入或添加到字符串中,字符串转换也会隐式发生,在这种情况下,不需要显式调用 toString
  • 截至 2018 年 4 月,单线在 iOS Safari 上对我有用
  • 您遇到什么错误,是什么版本的 Safari?也许new FormData(formElement) 那里还不支持?
  • @glebm 是的,它在 Safari 中不支持,你找到其他解决方案了吗?
【解决方案3】:

微型 from-serialize library 不依赖于框架。除此之外,您需要自己实现序列化功能。 (虽然重量为 1.2 KB,为什么不使用它?)

【讨论】:

  • 这太完美了。但不得不在代码的输入部分添加case 'email':
  • 哦,现在我明白了,如果没有 javascript,googlecode 就无法工作。它只是吐That's an error
  • 请包含一些代码,而不仅仅是指向库的链接。如果库是开源的,您应该能够复制相关代码。
【解决方案4】:
function serialize (form) {
    if (!form || form.nodeName !== "FORM") {
            return;
    }
    var i, j, q = [];
    for (i = form.elements.length - 1; i >= 0; i = i - 1) {
        if (form.elements[i].name === "") {
            continue;
        }
        switch (form.elements[i].nodeName) {
            case 'INPUT':
                switch (form.elements[i].type) {
                    case 'text':
                    case 'tel':
                    case 'email':
                    case 'hidden':
                    case 'password':
                    case 'button':
                    case 'reset':
                    case 'submit':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                    case 'checkbox':
                    case 'radio':
                        if (form.elements[i].checked) {
                                q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        }                                               
                        break;
                }
                break;
                case 'file':
                break; 
            case 'TEXTAREA':
                    q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                    break;
            case 'SELECT':
                switch (form.elements[i].type) {
                    case 'select-one':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                    case 'select-multiple':
                        for (j = form.elements[i].options.length - 1; j >= 0; j = j - 1) {
                            if (form.elements[i].options[j].selected) {
                                    q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].options[j].value));
                            }
                        }
                        break;
                }
                break;
            case 'BUTTON':
                switch (form.elements[i].type) {
                    case 'reset':
                    case 'submit':
                    case 'button':
                        q.push(form.elements[i].name + "=" + encodeURIComponent(form.elements[i].value));
                        break;
                }
                break;
            }
        }
    return q.join("&");
}

来源:http://code.google.com/p/form-serialize/source/browse/trunk/serialize-0.1.js

【讨论】:

  • 该序列化似乎与标准形式的序列化不兼容,其中空格由“+”表示。以上仅使用 encodeURIComponent,它将空间编码为“%20”。如果需要一致性,可以在末尾使用正则表达式将“%20”转换为“+”,然后再传输。
  • 我已经在gist.github.com/brettz9/7147458 中添加了这样一个修改版本(还有一些其他改进)
  • 提交按钮不一定要提交,重置按钮永远不应该提交,并且按钮仅用于提交并在这种情况下被视为提交按钮。见HTML5 4.10.22 Form submission
  • 不要序列化输入类型的电子邮件。
【解决方案5】:

这里是 TibTibs 的略微修改版本:

function serialize(form) {
    var field, s = [];
    if (typeof form == 'object' && form.nodeName == "FORM") {
        var len = form.elements.length;
        for (i=0; i<len; i++) {
            field = form.elements[i];
            if (field.name && !field.disabled && field.type != 'file' && field.type != 'reset' && field.type != 'submit' && field.type != 'button') {
                if (field.type == 'select-multiple') {
                    for (j=form.elements[i].options.length-1; j>=0; j--) {
                        if(field.options[j].selected)
                            s[s.length] = encodeURIComponent(field.name) + "=" + encodeURIComponent(field.options[j].value);
                    }
                } else if ((field.type != 'checkbox' && field.type != 'radio') || field.checked) {
                    s[s.length] = encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value);
                }
            }
        }
    }
    return s.join('&').replace(/%20/g, '+');
}

禁用的字段被丢弃,名称也被 URL 编码。 %20 个字符的正则表达式替换只发生一次,然后返回字符串。

查询字符串与 jQuery 的 $.serialize() 方法的结果形式相同。

【讨论】:

  • +1 用于花时间改进代码。当人们发现我的缺点时,我很享受,因为这是一个很好的学习机会。 +1 也让它看起来不错。 -1 因为我不能给 +2 =(
  • 你可以添加form.nodeName.toLowerCase() == "form"而不是form.nodeName == "FORM"
【解决方案6】:

如果您需要使用 POST 以 json 格式提交表单“myForm”,您可以这样做:

const formEntries = new FormData(myForm).entries();
const json = Object.assign(...Array.from(formEntries, ([x,y]) => ({[x]:y})));
fetch('/api/foo', {
  method: 'POST',
  body: JSON.stringify(json)
});

第二行从一个数组转换而来,如:

[["firstProp", "firstValue"], ["secondProp", "secondValue"], ...and so on... ]

...变成一个普通的对象,比如:

{"firstProp": "firstValue", "secondProp": "secondValue", ...and so on ... }

...它通过将 mapFn 传递给 Array.from() 来进行此转换。此 mapFn 应用于每个 ["a","b"] 对并将它们转换为 {"a": "b"} 以便数组包含许多对象,每个对象只有一个属性。 mapFn 使用“解构”来获取该对的第一部分和第二部分的名称,并且它还使用 ES6“ComputedPropertyName”来设置 mapFn 返回的对象中的属性名称(这就是为什么说“[ x]: something" 而不仅仅是 "x: something"。

然后将所有这些单一属性对象传递到 Object.assign() 函数的参数中,该函数将所有单一属性对象合并为具有所有属性的单一对象。

Array.from(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from

参数中的解构: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/

更多关于计算属性名称的信息: Variable as the property name in a JavaScript object literal?

【讨论】:

  • 它对我有用,即使我不明白第二行,你能提供更多关于它的信息吗??
  • 使用扩展运算符和原生 Object 和 Array 方法的漂亮答案。
  • 请注意,这种方法在 IE (.entries()) 中不受支持
  • Object.entries() 的 MDN 页面有一个简短的 polyfill,可用于 IE:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…,但 IE 也不支持扩展运算符。
  • 您可以使用新方法 Object.fromEntries(new FormData(myFormElement)) 序列化表单。
【解决方案7】:

我从 Johndave Decano 的回答开始。

这应该可以解决他的职能回复中提到的一些问题。

  1. 将 %20 替换为 + 符号。
  2. 提交/按钮类型只有在被点击后才会提交 提交表单。
  3. 重置按钮将被忽略。
  4. 代码对我来说似乎是多余的,因为它本质上是 无论字段类型如何,都是一样的。更何况 与“tel”和“email”等 HTML5 字段类型不兼容, 因此,我使用 switch 语句删除了大部分细节。

如果按钮类型没有名称值,它们仍然会被忽略。

function serialize(form, evt){
    var evt    = evt || window.event;
    evt.target = evt.target || evt.srcElement || null;
    var field, query='';
    if(typeof form == 'object' && form.nodeName == 'FORM'){
        for(i=form.elements.length-1; i>=0; i--){
            field = form.elements[i];
            if(field.name && field.type != 'file' && field.type != 'reset' && !field.disabled){
                if(field.type == 'select-multiple'){
                    for(j=form.elements[i].options.length-1; j>=0; j--){
                        if(field.options[j].selected){
                            query += '&' + field.name + "=" + encodeURIComponent(field.options[j].value).replace(/%20/g,'+');
                        }
                    }
                }
                else{
                    if((field.type != 'submit' && field.type != 'button') || evt.target == field){
                        if((field.type != 'checkbox' && field.type != 'radio') || field.checked){
                            query += '&' + field.name + "=" + encodeURIComponent(field.value).replace(/%20/g,'+');
                        }   
                    }
                }
            }
        }
    }
    return query.substr(1);
}

这就是我目前使用此功能的方式。

<form onsubmit="myAjax('http://example.com/services/email.php', 'POST', serialize(this, event))">

【讨论】:

  • +1 表示重构得很好。 -1 用于忽略不应该出现在查询字符串中的禁用字段。 +1 用于非常优雅的 for 语句,避免重复计算表单元素。总计:+1 :-) 谢谢!
  • 关于禁用字段的好注释,我最近在编写一个新函数时遇到了这个问题。 +1 给你们两个,因为我喜欢阅读有趣的 cmets。 :)
【解决方案8】:

适用于所有浏览器。

const formSerialize = formElement => {
  const values = {};
  const inputs = formElement.elements;

  for (let i = 0; i < inputs.length; i++) {
    values[inputs[i].name] = inputs[i].value;
  }
  return values;
}

const dumpValues = form => () => {
  
  const r = formSerialize(form);
  console.log(r);
  console.log(JSON.stringify(r));
}

const form = document.querySelector('form');

dumpValues(form)();

form.addEventListener('change',dumpValues(form));
<form action="/my-handling-form-page" method="post">
  <div>
    <label for="name">Name:</label>
    <input type="text" id="name" name="user_name" value="John">
  </div>
  <div>
    <label for="mail">E-mail:</label>
    <input type="email" id="mail" name="user_mail" value="john@jonhson.j">
  </div>
  <div>
    <label for="interests">Interest:</label>
    <select required=""  id="interests" name="interests">
      <option value="" selected="selected">- None -</option>
      <option value="drums">Drums</option>
      <option value="js">Javascript</option>
      <option value="sports">Sports</option>
      <option value="trekking">Trekking</option>
    </select>
  </div>
  <div>
    <label for="msg">Message:</label>
    <textarea id="msg" name="user_message">Hello My Friend</textarea>
  </div>
</form>

【讨论】:

  • 这个是 json,我猜作者是在问关于序列化到 URI 的问题。
  • 我很乐意看到这适用于多个选择选项表单。
  • @ZachSmith 它已经工作了,但我添加了一个示例供您检查
【解决方案9】:
HTMLElement.prototype.serialize = function(){
    var obj = {};
    var elements = this.querySelectorAll( "input, select, textarea" );
    for( var i = 0; i < elements.length; ++i ) {
        var element = elements[i];
        var name = element.name;
        var value = element.value;

        if( name ) {
            obj[ name ] = value;
        }
    }
    return JSON.stringify( obj );
}

这样使用:

var dataToSend = document.querySelector("form").serialize();

我希望我有所帮助。

【讨论】:

  • 不适用于复选框。在这里,您必须明确检查输入类型。
【解决方案10】:

如果您希望序列化事件的输入。这是我使用的纯 JavaScript 方法。

// serialize form
var data = {};
var inputs = [].slice.call(e.target.getElementsByTagName('input'));
inputs.forEach(input => {
  data[input.name] = input.value;
});

数据将是输入的 JavaScript 对象。

【讨论】:

  • 这应该适用于大多数元素。绝对不是 textarea/select,虽然
  • 那个 slice.call 和 Array.from 一样吗?
【解决方案11】:

@SimonSteinberger 代码的重构版本,使用更少的变量并利用forEach 循环的速度(比fors 快一点)

function serialize(form) {
    var result = [];
    if (typeof form === 'object' && form.nodeName === 'FORM')
        Array.prototype.slice.call(form.elements).forEach(function(control) {
            if (
                control.name && 
                !control.disabled && 
                ['file', 'reset', 'submit', 'button'].indexOf(control.type) === -1
            )
                if (control.type === 'select-multiple')
                    Array.prototype.slice.call(control.options).forEach(function(option) {
                        if (option.selected) 
                            result.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(option.value));
                    });
                else if (
                    ['checkbox', 'radio'].indexOf(control.type) === -1 || 
                    control.checked
                ) result.push(encodeURIComponent(control.name) + '=' + encodeURIComponent(control.value));
        });
        return result.join('&').replace(/%20/g, '+');
}

【讨论】:

    【解决方案12】:

    这可以通过以下非常简单的函数来完成

    function serialize(form) {
            let requestArray = [];
            form.querySelectorAll('[name]').forEach((elem) => {
                requestArray.push(elem.name + '=' + elem.value);
            });
            if(requestArray.length > 0)
                return requestArray.join('&');
            else
                return false;
        }
    
     serialized = serialize(document.querySelector('form'))
      console.log(serialized);
    <form>
    
      <input type='text' name='fname' value='Johne'/>
      <input type='text' name='lname' value='Doe'/>
      <input type='text' name='contact[]' value='99999999'/>
      <input type='text' name='contact[]' value='34423434345'/>
    
    </form>

    【讨论】:

      【解决方案13】:

      我将 TibTibs 的答案重构为更易于阅读的内容。由于 80 个字符的宽度和几个 cmets,它有点长。

      此外,它会忽略空白字段名称和空白值。

      // Serialize the specified form into a query string.
      //
      // Returns a blank string if +form+ is not actually a form element.
      function $serialize(form, evt) {
        if(typeof(form) !== 'object' && form.nodeName !== "FORM")
          return '';
      
        var evt    = evt || window.event || { target: null };
        evt.target = evt.target || evt.srcElement || null;
        var field, query = '';
      
        // Transform a form field into a query-string-friendly
        // serialized form.
        //
        // [NOTE]: Replaces blank spaces from its standard '%20' representation
        //         into the non-standard (though widely used) '+'.
        var encode = function(field, name) {
          if (field.disabled) return '';
      
          return '&' + (name || field.name) + '=' +
                 encodeURIComponent(field.value).replace(/%20/g,'+');
        }
      
        // Fields without names can't be serialized.
        var hasName = function(el) {
          return (el.name && el.name.length > 0)
        }
      
        // Ignore the usual suspects: file inputs, reset buttons,
        // buttons that did not submit the form and unchecked
        // radio buttons and checkboxes.
        var ignorableField = function(el, evt) {
          return ((el.type == 'file' || el.type == 'reset')
              || ((el.type == 'submit' || el.type == 'button') && evt.target != el)
              || ((el.type == 'checkbox' || el.type == 'radio') && !el.checked))
        }
      
        var parseMultiSelect = function(field) {
          var q = '';
      
          for (var j=field.options.length-1; j>=0; j--) {
            if (field.options[j].selected) {
              q += encode(field.options[j], field.name);
            }
          }
      
          return q;
        };
      
        for(i = form.elements.length - 1; i >= 0; i--) {
          field = form.elements[i];
      
          if (!hasName(field) || field.value == '' || ignorableField(field, evt))
            continue;
      
          query += (field.type == 'select-multiple') ? parseMultiSelect(field)
                                                     : encode(field);
        }
      
        return (query.length == 0) ? '' : query.substr(1);
      }
      

      【讨论】:

      • 我将它直接复制到我的应用程序中,但多选似乎不起作用(值重复)
      • @anastymous 感谢您的捕获,已修复。
      • 嗨,Brian,evt 是干什么用的?我应该为此传递什么? Firefox 告诉我它没有定义。
      • 嗨 anastymous,再次感谢您的捕获,它应该通过将分配到 evt 更改为 evt = evt || window.event || { target: null }; 来解决(正如编辑所做的那样)它背后的要点是传递触发序列化,如果有的话,比如表单的“提交”事件,或者按钮的“点击”。如果表单有多个提交按钮,您只需考虑触发事件的按钮的值,而忽略其他按钮。我在dump.bedmonds.net/serialize-js 上拼凑了一个关于这种行为的非常基本的例子
      【解决方案14】:

      我从@moison 答案和MDN 中获取了formData 的entry() 方法,据说:

      FormData.entries() 方法返回一个允许去的迭代器 通过此对象中包含的所有键/值对。每个的关键 pair 是一个 USVString 对象;值是 USVString 或 Blob。

      但唯一的问题是移动浏览器(不支持android和safari)以及IE和Safari桌面

      但基本上这是我的方法:

      let theForm =  document.getElementById("contact"); 
      
      theForm.onsubmit = function(event) {
          event.preventDefault();
      
          let rawData = new FormData(theForm);
          let data = {};
      
         for(let pair of rawData.entries()) {
           data[pair[0]] = pair[1]; 
          }
          let contactData = JSON.stringify(data);
          console.warn(contactData);
          //here you can send a post request with content-type :'application.json'
      
      };
      

      代码可以在here找到

      【讨论】:

        【解决方案15】:

        使用 JavaScript 的 reduce 函数应该适用于所有浏览器,包括 IE9 >:

        Array.prototype.slice.call(form.elements) // convert form elements to array
            .reduce(function(acc,cur){   // reduce 
                var o = {type : cur.type, name : cur.name, value : cur.value}; // get needed keys
                if(['checkbox','radio'].indexOf(cur.type) !==-1){
                    o.checked = cur.checked;
                } else if(cur.type === 'select-multiple'){
                    o.value=[];
                    for(i=0;i<cur.length;i++){
                        o.value.push({
                            value : cur.options[i].value,
                            selected : cur.options[i].selected
                        });
                    }
                }
                acc.push(o);
                return acc;
         },[]);
        

        下面的实时示例。

        var _formId = document.getElementById('formId'),
            formData = Array.prototype.slice.call(_formId.elements).reduce(function(acc,cur,indx,arr){
                var i,o = {type : cur.type, name : cur.name, value : cur.value};
                if(['checkbox','radio'].indexOf(cur.type) !==-1){
                    o.checked = cur.checked;
                } else if(cur.type === 'select-multiple'){
                    o.value=[];
                    for(i=0;i<cur.length;i++){
                        o.value.push({
                            value : cur.options[i].value,
                            selected : cur.options[i].selected
                        });
                    }
                }
                acc.push(o);
                return acc;
            },[]);
        
        // view
        document.getElementById('formOutput').innerHTML = JSON.stringify(formData, null, 4);
        <form id="formId">
            <input type="text" name="texttype" value="some text">
            <select>
                <option value="Opt 1">Opt 1</option>
                <option value="Opt 2" selected>Opt 2</option>
                <option value="Opt 3">Opt 3</option>
            </select>
            <input type="checkbox" name="checkboxtype" value="Checkbox 1" checked> Checkbox 1
            <input type="checkbox" name="checkboxtype" value="Checkbox 2"> Checkbox 2
            <input type="radio" name="radiotype" value="Radio Btn 1"> Radio Btn 1
            <input type="radio" name="radiotype" value="Radio Btn 2" checked> Radio Btn 2
            <select multiple>
                <option value="Multi 1" selected>Multi 1</option>
                <option value="Multi 2">Saab</option>
                <option value="Multi 3" selected>Multi 3</option>
            </select>
        </form>
        <pre><code id="formOutput"></code></pre>

        【讨论】:

        • 这对多选有用吗?似乎当我使用您的代码时,它只返回多个选定选项值的第一项
        • @ZachSmith 我已更新我的答案以包含多个选择元素。
        【解决方案16】:

        我的方式...

        const myForm = document.forms['form-name']
        
        myForm.onsubmit=e=>
          {
          e.preventDefault()  // for testing...
        
          let data = Array.from(new FormData(myForm))
                          .reduce((r,[k,v])=>{r[k]=v;return r},{})
        
          /*_______________________________________ same code: for beginners 
          let data = {}
          Array.from(new FormData(myForm), (entry) => { data[ entry[0] ] = entry[1]} )
          ________________________________________________________________*/
         
          console.log(data)
          
          //...
          }
        

        【讨论】:

          【解决方案17】:
            // supports IE8 and IE9 
            function serialize(form) {
              var inputs = form.elements;
              var array = [];
              for(i=0; i < inputs.length; i++) {
                var inputNameValue = inputs[i].name + '=' + inputs[i].value;
                array.push(inputNameValue);
              }
              return array.join('&');
            }
           //using the serialize function written above
           var form = document.getElementById("form");//get the id of your form. i am assuming the id to be named form.
           var form_data = serialize(form);
           var xhr = new XMLHttpRequest();
           xhr.send(form_data);
          
           //does not work with IE8 AND IE9
           var form = document.querySelector('form');
           var data = new FormData(form);
           var xhr = new XMLHttpRequest();
           xhr.send(data);
          

          【讨论】:

            【解决方案18】:

            改进 David Lemon 的回答。

            这会将表单数据转换为 JSON,并允许您从数据对象设置表单。

            const main = () => {
              const form = document.forms['info'];
              const data = {
                "user_name"       : "John",
                "user_email"      : "john@jonhson.com",
                "user_created"    : "2020-03-24",
                "user_age"        : 42,
                "user_subscribed" : true,
                "user_interests"  : "sports",
                "user_message"    : "Hello My Friend"
              };
            
              populateForm(form, data);
              updateJsonView(form);
              form.addEventListener('change', (e) => updateJsonView(form));
            }
            
            const getFieldValue = (field, opts) => {
              let type = field.getAttribute('type');
              if (type) {
                switch (type) {
                  case 'checkbox':
                    return field.checked;
                  case 'number':
                    return field.value.includes('.')
                      ? parseFloat(field.value)
                      : parseInt(field.value, 10);
                }
              }
              if (opts && opts[field.name] && opts[field.name].type) {
                switch (opts[field.name].type) {
                  case 'int':
                    return parseInt(field.value, 10);
                  case 'float':
                    return parseFloat(field.value);
                }
              }
              return field.value;
            }
            
            const setFieldValue = (field, value) => {
              let type = field.getAttribute('type');
              if (type) {
                switch (type) {
                  case 'checkbox':
                    field.checked = value;
                    break;
                  default:
                    field.value = value;
                    break;
                }
              } else {
                field.value = value;
              }
            }
            
            const extractFormData = (form, opts) => {
              return Array.from(form.elements).reduce((data, element) => {
                return Object.assign(data, { [element.name] : getFieldValue(element, opts) });
              }, {});
            };
            
            const populateForm = (form, data) => {
              return Array.from(form.elements).forEach((element) => {
                setFieldValue(element, data[element.name]);
              });
            };
            
            const updateJsonView = (form) => {
              let fieldOptions = {};
              let formData = extractFormData(form, fieldOptions);
              let serializedData = JSON.stringify(formData, null, 2);
              document.querySelector('.json-view').textContent = serializedData;
            };
            
            main();
            .form-field {
              margin-bottom: 0.5em;
            }
            
            .form-field label {
              display: inline-block;
              font-weight: bold;
              width: 7em;
              vertical-align: top;
            }
            
            .json-view {
              position: absolute;
              top: 0.667em;
              right: 0.667em;
              border: thin solid grey;
              padding: 0.5em;
              white-space: pre;
              font-family: monospace;
              overflow: scroll-y;
              max-height: 100%;
            }
            <form name="info" action="/my-handling-form-page" method="post">
              <div class="form-field">
                <label for="name">Name:</label>
                <input type="text" id="name" name="user_name">
              </div>
              <div class="form-field">
                <label for="mail">E-mail:</label>
                <input type="email" id="mail" name="user_email">
              </div>
              <div class="form-field">
                <label for="created">Date of Birth:</label>
                <input type="date" id="created" name="user_created">
              </div>
              <div class="form-field">
                <label for="age">Age:</label>
                <input type="number" id="age" name="user_age">
              </div>
              <div class="form-field">
                <label for="subscribe">Subscribe:</label>
                <input type="checkbox" id="subscribe" name="user_subscribed">
              </div>
              <div class="form-field">
                <label for="interests">Interest:</label>
                <select required=""  id="interests" name="user_interests">
                  <option value="" selected="selected">- None -</option>
                  <option value="drums">Drums</option>
                  <option value="js">Javascript</option>
                  <option value="sports">Sports</option>
                  <option value="trekking">Trekking</option>
                </select>
              </div>
              <div class="form-field">
                <label for="msg">Message:</label>
                <textarea id="msg" name="user_message"></textarea>
              </div>
            </form>
            <div class="json-view"></div>

            【讨论】:

              【解决方案19】:

              这是纯 JavaScript 方法:

              var form = document.querySelector('form');
              var data = new FormData(form);
              
                var xhttp = new XMLHttpRequest();
                xhttp.onreadystatechange = function() {
                  if (this.readyState == 4 && this.status == 200) {
                     console.log(this.responseText);
                  }
                };
                xhttp.open("POST", "<YOUR-URL>", true);
                xhttp.send(data);
              }
              

              【讨论】:

                【解决方案20】:

                这是我的解决方案 -

                JsonStringifyForm: function(formId) {
                      let myForm = document.getElementById(formId);
                      let formData = new FormData(myForm);
                      const data = {}; // need to convert it before using not with XMLHttpRequest
                      for (let [key, val] of formData.entries()) {
                        Object.assign(data, { [key]: val });
                      }
                      return JSON.stringify(data);
                    }
                

                【讨论】:

                  【解决方案21】:

                  您可以使用 Object.fromEntries 如下

                  function parseForm(e) {
                    const formData = new FormData(e.target);
                    return Object.fromEntries(formData.entries());
                  }
                  
                  

                  【讨论】:

                    【解决方案22】:

                    我希望这会奏效

                    var serializeForm = (formElement) => {
                      const formData = {};
                      const inputs = formElement.elements;
                    
                      for (let i = 0; i < inputs.length; i++) {
                        if(inputs[i].name!=="")
                            formData[inputs[i].name] = inputs[i].value;
                      }
                      return formData;
                    }
                    

                    【讨论】:

                      【解决方案23】:

                      出于调试目的,这可能会对您有所帮助:

                      function print_form_data(form) {
                          const form_data = new FormData(form);
                      
                          for (const item of form_data.entries()) {
                              console.log(item);
                          }
                      
                          return false;
                      }
                      

                      【讨论】:

                        【解决方案24】:

                        我可能疯了,但我发现这些答案严重臃肿。这是我的解决方案

                        function serialiseForm(form) {
                          var input = form.getElementsByTagName("input");
                          var formData = {};
                          for (var i = 0; i < input.length; i++) {
                            formData[input[i].name] = input[i].value;
                          }
                          return formData = JSON.stringify(formData);
                        }
                        

                        【讨论】:

                        • 基于您的表单以按输入类型检索元素将失败 select
                        【解决方案25】:

                        我喜欢这个库:https://github.com/macek/jquery-serialize-object(1.7KB 大小)

                        给定一个基本的 HTML 表单:

                        <form id="contact">
                          <input name="user[email]" value="jsmith@example.com">
                          <input name="user[pets][]" type="checkbox" value="cat" checked>
                          <input name="user[pets][]" type="checkbox" value="dog" checked>
                          <input name="user[pets][]" type="checkbox" value="bird">
                          <input type="submit">
                        </form>
                        

                        .serializeObject — 将选定的表单序列化为 JavaScript 对象

                        $('form#contact').serializeObject();
                        //=> {user: {email: "jsmith@example.com", pets: ["cat", "dog"]}}
                        

                        主要风格

                        push — 将值推送到数组

                        <input name="foo[]" value="a">
                        <input name="foo[]" value="b">
                        
                        $("form").serializeObject();
                        //=> {foo: [a, b]}
                        

                        固定 — 将值添加到指定索引处的数组

                        <input name="foo[2]" value="a">
                        <input name="foo[4]" value="b">
                        
                        $("form").serializeObject();
                        //=> {foo: [, , "a", , "b"]}
                        

                        named — 为指定的键添加一个值

                        <input name="foo[bar]" value="a">
                        <input name="foo[bof]" value="b">
                        <input name="hello" value="world">
                        
                        $("form").serializeObject();
                        //=> {foo: {bar: "a", bof: "b"}, hello: "world"}
                        

                        类似的库(更活跃):https://github.com/marioizquierdo/jquery.serializeJSON

                        类似的库(非常活跃):https://github.com/brainfoolong/form-data-json 使用最后一个,您不仅可以序列化数据,反之亦然:为表单字段设置值

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2015-07-06
                          • 2018-11-24
                          • 2018-09-13
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多