[javascript] 직렬화 자바 스크립트 양식 (프레임 워크 없음)

jquery 또는 프레임 워크없이 양식을 직렬화하고 직렬화 된 버전에 액세스 할 수있는 프레임 워크가없는 Javascript 기능이 있습니까?



답변

소형 직렬화 라이브러리 는 프레임 워크에 의존하지 않습니다. 이와 같은 것 외에 직렬화 기능을 직접 구현해야합니다. (무게 1.2 킬로바이트이지만 사용하지 않겠습니까?)


답변

순수한 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


답변

최신 브라우저 만

URLSearchParamsAPI ( 가장 최근 브라우저 ) 및 FormData(formElement)생성자 ( 가장 최근 브라우저 제외 ) 를 지원하는 브라우저를 대상으로하는 경우 다음을 사용하십시오.

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

IE를 제외한 모든 곳

생성자 를 지원 URLSearchParams하지만 지원 하지 않는 브라우저의 경우이 FormData polyfill 및이 코드를 사용하십시오 (IE를 제외한 모든 곳에서 작동).FormData(formElement)

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

IE 10과 호환

구형 브라우저 (예 : IE 10)의 경우 FormData polyfill , Array.from필요한 경우 polyfill 및이 코드를 사용하십시오.

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


답변

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


답변

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 () 메서드의 결과와 동일한 형식입니다.


답변

나는 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'){
                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))">


답변

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

두 번째 줄은 다음과 같은 배열에서 변환됩니다.

[["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] : “x : 무엇인가”보다는 “”

이 모든 단일 속성 개체는 모든 단일 속성 개체를 모든 속성을 가진 단일 개체로 병합하는 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/

: 자세한 내용은 여기 계산 된 속성 이름에
자바 스크립트 객체 리터럴에서 속성 이름과 변수?