Javascript 表单序列化javascript(无框架)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11661187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 06:41:14  来源:igfitidea点击:

form serialize javascript (no framework)

javascriptformsserialization

提问by RussellHarrower

Wondering is there a function in javascript without jquery or any framework that allows me to serialize the form and access the serialized version?

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

采纳答案by Lusitanian

The miniature from-serialize librarydoesn't rely on a framework. Other than something like that, you'll need to implement the serialization function yourself. (though at a weight of 1.2 kilobytes, why not use it?)

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

回答by Artur Beljajev

Here is pure JavaScript approach:

这是纯 JavaScript 方法:

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

Though it seems to be working only for POST requests.

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

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

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

回答by glebm

For modern browsers only

仅适用于现代浏览器

If you target browsers that support the URLSearchParamsAPI (most recent browsers) and FormData(formElement)constructor (most recent browsersexcept Edge), use this:

如果您的目标浏览器支持URLSearchParamsAPI(最新浏览器)和FormData(formElement)构造函数(除 Edge 之外的最新浏览器),请使用:

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

Everywhere except IE

除了 IE 之外的所有地方

For browsers that support URLSearchParamsbut not the FormData(formElement)constructor, use this FormData polyfilland this code (works everywhere except IE):

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

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

Example

例子

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/[email protected]/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>

Compatible with IE 10

与 IE 10 兼容

For even older browsers (e.g. IE 10), use the FormData polyfill, an Array.frompolyfill if necessary and this code:

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

Array.from(
  new FormData(formElement),
  e => e.map(encodeURIComponent).join('=')
).join('&')

回答by Johndave Decano

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("&");
}

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

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

回答by Simon Steinberger

Here's a slightly modified version of TibTibs':

这是 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, '+');
}

Disabled fields are discarded and names are also URL encoded. Regex replace of %20 characters takes place only once, before returning the string.

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

The query string is in identical form to the result from jQuery's $.serialize() method.

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

回答by TibTibs

I started with the answer from Johndave Decano.

我从 Johndave Decano 的回答开始。

This should fix a few of the issues mentioned in replies to his function.

这应该可以解决对他的功能的答复中提到的一些问题。

  1. Replace %20 with a + symbol.
  2. Submit/Button types will only be submitted if they were clicked to submit the form.
  3. Reset buttons will be ignored.
  4. The code seemed redundant to me since it is doing essentially the same thing regardless of the field types. Not to mention incompatibility with HTML5 field types such as 'tel' and 'email', thus I removed most of the specifics with the switch statements.
  1. 用 + 符号替换 %20。
  2. 提交/按钮类型只有在点击提交表单时才会提交。
  3. 重置按钮将被忽略。
  4. 代码对我来说似乎是多余的,因为无论字段类型如何,它都在做本质上相同的事情。更不用说与 HTML5 字段类型(例如“电话”和“电子邮件”)的不兼容性,因此我删除了 switch 语句中的大部分细节。

Button types will still be ignored if they don't have a name value.

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

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'){
                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);
}

This is how I am currently using this function.

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

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

回答by molsson

If you need to submit form "myForm" using POST in json format you can do:

如果您需要使用 JSON 格式的 POST 提交表单“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)
});

The second line converts from an array like:

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

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

...into a regular object, like:

...进入常规对象,例如:

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

...it does this conversion by passing in a mapFn into Array.from(). This mapFn is applied to each ["a","b"] pair and converts them into {"a": "b"} so that the array contains a lot of object with only one property in each. The mapFn is using "destructuring" to get names of the first and second parts of the pair, and it is also using an ES6 "ComputedPropertyName" to set the property name in the object returned by the mapFn (this is why is says "[x]: something" rather than just "x: something".

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

All of these single property objects are then passed into arguments of the Object.assign() function which merges all the single property objects into a single object that has all properties.

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

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

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

Destructuring in parameters: https://simonsmith.io/destructuring-objects-as-function-parameters-in-es6/

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

More on computed property names here: Variable as the property name in a JavaScript object literal?

有关计算属性名称的更多信息: 变量作为 JavaScript 对象字面量中的属性名称?

回答by David Lemon

Works in all browsers.

适用于所有浏览器。

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="[email protected]">
  </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>

回答by Eduardo Borges

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

To use like this:

像这样使用:

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

I hope I have helped.

我希望我有所帮助。

回答by CAOakley

If you are looking to serialize the inputs on an event. Here's a pure JavaScript approach I use.

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

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

Data will be a JavaScript object of the inputs.

数据将是输入的 JavaScript 对象。