HTML5 FormData 객체를 JSON으로 변환하는 방법은 무엇입니까? Jquery없이 FormData의 중첩 된 속성을 객체처럼 처리합니다.
답변
당신은 또한 사용할 수있는 forEach
온 FormData
직접 객체 :
var object = {};
formData.forEach(function(value, key){
object[key] = value;
});
var json = JSON.stringify(object);
최신 정보:
ES6 화살표 기능 과 동일한 솔루션을 선호하는 사람들을 위해 :
var object = {};
formData.forEach((value, key) => object[key] = value);
var json = JSON.stringify(object);
업데이트 2 :
그리고 다중 선택 목록 또는 여러 값을 가진 다른 양식 요소에 대한 지원을 원하는 사람들을 위해 (이 문제에 대한 답변 아래에 너무 많은 주석이 있기 때문에 가능한 해결책을 추가 할 것입니다) :
var object = {};
formData.forEach((value, key) => {
// Reflect.has in favor of: object.hasOwnProperty(key)
if(!Reflect.has(object, key)){
object[key] = value;
return;
}
if(!Array.isArray(object[key])){
object[key] = [object[key]];
}
object[key].push(value);
});
var json = JSON.stringify(object);
여기 간단한 다중 선택 목록과 함께이 방법의 사용을 보여주는 Fiddle 이 있습니다.
업데이트 3 :
여기서 끝나는 사람들에 대한 부수적으로, 양식 데이터를 json으로 변환하는 목적이 XML HTTP 요청을 통해 서버로 보내는 FormData
것이라면 변환하지 않고 직접 객체를 보낼 수 있습니다 . 다음과 같이 간단합니다.
var request = new XMLHttpRequest();
request.open("POST", "http://example.com/submitform.php");
request.send(formData);
참조 를 위해 MDN에서 FormData 객체 사용 을 참조하십시오 .
업데이트 4 :
내 답변 아래의 주석 중 하나에서 언급했듯이 JSON stringify
메서드는 모든 유형의 개체에 대해 즉시 작동하지 않습니다. 지원되는 유형에 대한 자세한 내용 은의 MDN 설명서에서 설명 섹션JSON.stringify
을 참조하고 싶습니다 .
설명에서 다음과 같이 언급됩니다.
값에 toJSON () 메서드가있는 경우 직렬화 할 데이터를 정의해야합니다.
즉, toJSON
사용자 지정 개체를 직렬화하는 논리와 함께 고유 한 직렬화 메서드를 제공 할 수 있습니다 . 이와 같이보다 복잡한 개체 트리에 대한 직렬화 지원을 빠르고 쉽게 구축 할 수 있습니다.
답변
2019 년에는 이런 종류의 작업이 매우 쉬워졌습니다.
JSON.stringify(Object.fromEntries(formData));
Object.fromEntries
: Chrome 73+, Firefox 63+, Safari 12.1에서 지원됨
답변
다음은 라이브러리를 사용하지 않고보다 기능적인 스타일로 수행하는 방법입니다.
Array.from(formData.entries()).reduce((memo, pair) => ({
...memo,
[pair[0]]: pair[1],
}), {});
예:
document.getElementById('foobar').addEventListener('submit', (e) => {
e.preventDefault();
const formData = new FormData(e.target);
const data = Array.from(formData.entries()).reduce((memo, pair) => ({
...memo,
[pair[0]]: pair[1],
}), {});
document.getElementById('output').innerHTML = JSON.stringify(data);
});
<form id='foobar'>
<input name='baz' />
<input type='submit' />
</form>
<pre id='output'>Input some value and submit</pre>
답변
예를 들어 같은 이름의 항목이 여러 개있는 경우, 예를 들어 같은 이름의 항목을 여러 개 사용 <SELECT multiple>
하거나 가지고있는 경우 <INPUT type="checkbox">
이를 처리하고 값의 배열을 만들어야합니다. 그렇지 않으면 마지막으로 선택한 값만 가져옵니다.
다음은 최신 ES6 변형입니다.
function formToJSON( elem ) {
let output = {};
new FormData( elem ).forEach(
( value, key ) => {
// Check if property already exist
if ( Object.prototype.hasOwnProperty.call( output, key ) ) {
let current = output[ key ];
if ( !Array.isArray( current ) ) {
// If it's not an array, convert it to an array.
current = output[ key ] = [ current ];
}
current.push( value ); // Add the new value to the array.
} else {
output[ key ] = value;
}
}
);
return JSON.stringify( output );
}
(이 지원하지 않기 때문에 여전히 IE11에서 지원하지 않는하지만 약간 오래된 코드 ForEach
나 entries
에 대한 FormData
)
function formToJSON( elem ) {
var current, entries, item, key, output, value;
output = {};
entries = new FormData( elem ).entries();
// Iterate over values, and assign to item.
while ( item = entries.next().value )
{
// assign to variables to make the code more readable.
key = item[0];
value = item[1];
// Check if key already exist
if (Object.prototype.hasOwnProperty.call( output, key)) {
current = output[ key ];
if ( !Array.isArray( current ) ) {
// If it's not an array, convert it to an array.
current = output[ key ] = [ current ];
}
current.push( value ); // Add the new value to the array.
} else {
output[ key ] = value;
}
}
return JSON.stringify( output );
}
답변
FormData () 객체를 사용하여이를 수행 할 수 있습니다 . 이 FormData 객체는 키에 대한 각 요소의 이름 속성과 값에 대해 제출 된 값을 사용하여 양식의 현재 키 / 값으로 채워집니다. 또한 파일 입력 내용을 인코딩합니다.
예:
var myForm = document.getElementById('myForm');
myForm.addEventListener('submit', function(event)
{
event.preventDefault();
var formData = new FormData(myForm),
result = {};
for (var entry of formData.entries())
{
result[entry[0]] = entry[1];
}
result = JSON.stringify(result)
console.log(result);
});
답변
사용하기 쉬운 기능
나는 이것을 위한 기능을 만들었다
function FormDataToJSON(FormElement){
var formData = new FormData(FormElement);
var ConvertedJSON= {};
for (const [key, value] of formData.entries())
{
ConvertedJSON[key] = value;
}
return ConvertedJSON
}
사용 예
var ReceivedJSON = FormDataToJSON(document.getElementById('FormId');)
이 코드에서는 for
루프를 사용하여 빈 JSON 변수를 만들었습니다 key
. 모든 반복에서 formData 객체에서 JSON 키로 s를 사용 했습니다.
이 코드는 GitHub의 내 JS 라이브러리에서 찾을 수 있습니다. 개선이 필요한 경우 여기에 코드를 배치했습니다 https://github.com/alijamal14/Utilities/blob/master/Utilities.js
답변
이 게시물은 이미 1 년이 지났지 만 ES6 @dzuc 답변이 정말 마음에 듭니다. 그러나 여러 선택 또는 확인란을 처리 할 수 없기 때문에 불완전합니다. 이것은 이미 지적되었고 코드 솔루션이 제공되었습니다. 무겁고 최적화되지 않았습니다. 그래서 이러한 경우를 처리하기 위해 @dzuc를 기반으로 2 가지 버전을 작성했습니다.
- 여러 항목 이름이 단순하게 반복 될 수있는 ASP 스타일 양식의 경우.
let r=Array.from(fd).reduce(
(o , [k,v]) => (
(!o[k])
? {...o , [k] : v}
: {...o , [k] : [...o[k] , v]}
)
,{}
);
let obj=JSON.stringify(r);
한 줄 핫샷 버전 :
Array.from(fd).reduce((o,[k,v])=>((!o[k])?{...o,[k]:v}:{...o,[k]:[...o[k],v]}),{});
- 여러 항목 이름에
[]
접미사 가 있어야하는 PHP 스타일 양식의 경우 .
let r=Array.from(fd).reduce(
(o , [k,v]) => (
(k.split('[').length>1)
? (k=k.split('[')[0]
, (!o[k])
? {...o , [k] : [v]}
: {...o , [k] : [...o[k] , v ]}
)
: {...o , [k] : v}
)
,{}
);
let obj=JSON.stringify(r);
한 줄 핫샷 버전 :
Array.from(fd).reduce((o,[k,v])=>((k.split('[').length>1)?(k=k.split('[')[0],(!o[k])?{...o,[k]:[v]}:{...o,[k]:[...o[k],v]}):{...o,[k]:v}),{});
- 다단계 배열을 지원하는 PHP 형식의 확장.
지난 두 번째 사례를 작성한 이후로 직장에서 PHP 양식에 여러 수준의 확인란이있는 경우가 발생했습니다. 이전 케이스와이 케이스를 지원하기 위해 새 케이스를 작성했습니다. 이 사례를 더 잘 보여주기 위해 스 니펫을 만들었습니다. 결과는이 데모의 콘솔에 표시되며 필요에 따라 수정합니다. 성능 저하없이 최선을 다해 최적화하려고했지만 사람의 가독성을 떨어 뜨 렸습니다. 배열은 객체이고 배열을 가리키는 변수는 참조로 유지된다는 이점이 있습니다. 이것에 대한 핫샷은 없습니다.
let nosubmit = (e) => {
e.preventDefault();
const f = Array.from(new FormData(e.target));
const obj = f.reduce((o, [k, v]) => {
let a = v,
b, i,
m = k.split('['),
n = m[0],
l = m.length;
if (l > 1) {
a = b = o[n] || [];
for (i = 1; i < l; i++) {
m[i] = (m[i].split(']')[0] || b.length) * 1;
b = b[m[i]] = ((i + 1) == l) ? v : b[m[i]] || [];
}
}
return { ...o, [n]: a };
}, {});
console.log(obj);
}
document.querySelector('#theform').addEventListener('submit', nosubmit, {capture: true});
<h1>Multilevel Form</h1>
<form action="#" method="POST" enctype="multipart/form-data" id="theform">
<input type="hidden" name="_id" value="93242" />
<input type="hidden" name="_fid" value="45c0ec96929bc0d39a904ab5c7af70ef" />
<label>Select:
<select name="uselect">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
</select>
</label>
<br /><br />
<label>Checkboxes one level:<br/>
<input name="c1[]" type="checkbox" checked value="1"/>v1
<input name="c1[]" type="checkbox" checked value="2"/>v2
<input name="c1[]" type="checkbox" checked value="3"/>v3
</label>
<br /><br />
<label>Checkboxes two levels:<br/>
<input name="c2[0][]" type="checkbox" checked value="4"/>0 v4
<input name="c2[0][]" type="checkbox" checked value="5"/>0 v5
<input name="c2[0][]" type="checkbox" checked value="6"/>0 v6
<br/>
<input name="c2[1][]" type="checkbox" checked value="7"/>1 v7
<input name="c2[1][]" type="checkbox" checked value="8"/>1 v8
<input name="c2[1][]" type="checkbox" checked value="9"/>1 v9
</label>
<br /><br />
<label>Radios:
<input type="radio" name="uradio" value="yes">YES
<input type="radio" name="uradio" checked value="no">NO
</label>
<br /><br />
<input type="submit" value="Submit" />
</form>