객체 문자열을 JSON으로 변환


165

JavaScript (또는 jQuery)를 사용하여 객체를 설명하는 문자열을 JSON 문자열로 변환하려면 어떻게해야합니까?

예 :이 (변환 하지 유효한 JSON 문자열) :

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"

이것으로 :

str = '{ "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] }'

eval()가능한 경우 사용을 피하고 싶습니다 .


왜 문자열이 JSON이 유효하지 않습니까? 어떻게 생성합니까?
로켓 Hazmat

2
문자열은 data다음 <div data-object="{hello:'world'}"></div>과 같이 -attrubute에 저장됩니다. HTML에서 작은 따옴표를 사용하고 싶지 않습니다 (따라서 신뢰할 수 없음)
snorpey

5
@ snorpey : <div data-object='{"hello":"world"}'></div>100 % 유효한 HTML입니다 (작은 따옴표는 그것을 신뢰하는 것과 관련이 있습니까?). 이런 식으로하면 그냥 할 수 있고 JSON.parse잘 작동합니다. 참고 : 키도 인용해야합니다.
로켓 Hazmat

노력에 대한 @Rocket 감사합니다! HTML에서 작은 따옴표를 사용해야하는 방법 (100 % 유효하더라도)과 JSON 표기법을 찾고 싶었습니다.
snorpey

@ snorpey : JSON을 HTML 속성에 넣지 않는 것이 우선입니다. 큰 따옴표를 사용하고 JSON의 따옴표를 이스케이프 할 수 있다고 생각합니다 <div data-object="{\"hello\":\"world\"}"></div>. 속성에 유효한 JSON을 사용하지 않으려면 고유 한 형식을 만들어 직접 구문 분석해야합니다.
로켓 Hazmat

답변:


181

문자열이 원본을 신뢰할 경우 , 당신은 사용할 수있는 eval다음 JSON.stringify결과를. 이처럼 :

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
var json = JSON.stringify(eval("(" + str + ")"));

이 때주의 eval객체 리터럴은 괄호에 싸여되어야한다 그렇지 않으면 중괄호 블록 대신 대상으로 분석된다.

또한 유효한 JSON으로 객체를 인코딩하여 구문 분석, 인코딩 및 다시 구문 분석하지 않아도되는 것이 훨씬 낫다는 질문 아래 의견에 동의 합니다 . HTML은 작은 따옴표 속성을 지원합니다 (문자열 안에 작은 따옴표를 HTML로 인코딩해야합니다).


문자열이 신뢰할 수있는 소스에서 온 경우 이것이 의미가 없습니다. 대신 문자열을 대신 변환하여 유효한 json으로 만듭니다.
allenhwkim

2
@allenhwkim 아이디어는 유효하지 않은 JSON에서 유효한 JSON으로 eval변환하는 것이므로 문자열을 JavaScript 객체로 변환합니다 (유효한 JSON이 아니더라도 문자열이 유효한 JavaScript를 나타내는 한 작동 함). 그런 다음 JSON.stringify객체에서 (유효한) JSON 문자열로 다시 변환합니다. eval문자열이 문자 그대로 JavaScript를 실행하여 사이트 간 스크립팅 공격의 가능성이 있기 때문에 신뢰할 수있는 소스에서 가져온 것이 아닌 경우 호출하는 것은 위험합니다.
Matthew Crumley

2
문자열이 구성된 경우 eval은이 경우에도 여전히 나쁜 일을합니다. var str = "(function () {console.log (\"bad \ ")}) ()";
Rondo

eval ()을 사용하면 JS 코드가 실행됩니다. 쉽게 남용 될 수 있습니다.
FisNaN

@allenhwkim : 우리는 어떤 소스도 신뢰하지 않습니다. IT에 대한 신뢰는 확인, 확인 및 다시 확인을 의미합니다.
Laszlo Varga

110

문자열이 유효한 JSON이 아니므로 JSON.parse(또는 jQuery 's $.parseJSON)가 작동하지 않습니다.

한 가지 방법은 eval"유효하지 않은"JSON을 "구문 분석"한 다음 stringify유효한 JSON으로 "변환"하는 것입니다.

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }"
str = JSON.stringify(eval('('+str+')'));

잘못된 JSON을 "수정"하는 대신 먼저 유효한 JSON으로 시작하는 것이 좋습니다. 어떻게 str생성되고 있는지, 생성되기 전에 수정해야합니다.

편집 : 당신은 (주석에서)이 문자열은 데이터 속성에 저장되어 있다고 말했습니다.

<div data-object="{hello:'world'}"></div>

나는 당신이 여기에 그것을 고치라고 제안하므로 JSON.parsed 일 수 있습니다 . 먼저 키와 값을 모두 큰 따옴표로 묶어야합니다. 다음과 같아야합니다 (HTML의 작은 따옴표로 묶은 속성이 유효 함).

<div data-object='{"hello":"world"}'></div>

이제 JSON.parse(또는 jQuery 's $.parseJSON)를 사용할 수 있습니다 .

var str = '{"hello":"world"}';
var obj = JSON.parse(str);

49

jQuery.parseJSON

str = jQuery.parseJSON(str)

편집하다. 유효한 JSON 문자열이 제공됩니다.


1
사실 JSON 문자열을 객체로 변환하는 방법으로 질문을 보았습니다
Farmor

43

아래 링크에서 간단한 코드를 사용하십시오.

http://msdn.microsoft.com/es-es/library/ie/cc836466%28v=vs.94%29.aspx

var jsontext = '{"firstname":"Jesper","surname":"Aaberg","phone":["555-0100","555-0120"]}';
var contact = JSON.parse(jsontext);

그리고 반대로

var str = JSON.stringify(arr);

타입 안전을 위해 새로운 String (jsontext)을 통해 jsontext를 String 객체로 변환하는 것이 더 좋습니다.
퍼지 분석

@fuzzyanalysis : 아니요, 기본 래퍼를 사용해서는 안됩니다.
Ry-

1
JSON.parse ()는 @LouiseMcMahon
pixel 67

24

이 작은 함수가 잘못된 JSON 문자열을 유효한 것으로 변환하기를 바랍니다.

function JSONize(str) {
  return str
    // wrap keys without quote with valid double quote
    .replace(/([\$\w]+)\s*:/g, function(_, $1){return '"'+$1+'":'})    
    // replacing single quote wrapped ones to double quote 
    .replace(/'([^']+)'/g, function(_, $1){return '"'+$1+'"'})         
}

결과

var invalidJSON = "{ hello: 'world',foo:1,  bar  : '2', foo1: 1, _bar : 2, $2: 3, 'xxx': 5, \"fuz\": 4, places: ['Africa', 'America', 'Asia', 'Australia'] }"
JSON.parse(invalidJSON) 
//Result: Uncaught SyntaxError: Unexpected token h VM1058:2
JSON.parse(JSONize(invalidJSON)) 
//Result: Object {hello: "world", foo: 1, bar: "2", foo1: 1, _bar: 2…}

JSON을 사용하여 b를 e-evalify하려고합니다. 코드를 구문 분석하면 좋은 솔루션처럼 보입니다. 우리는 여전히 손으로 지속적인 교체를 처리해야하지만 적어도 이것은 그러한 경우를 포함 할 수 있습니다.
ravemir

1
거의 완벽합니다. : 값 중 하나에 있으면 작동하지 않습니다 .
seler

9

주의해서 사용하십시오 eval():

function strToJson(str) {
  eval("var x = " + str + ";");
  return JSON.stringify(x);
}

전화 :

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
alert( strToJson(str) );

3
익명의 다운 투표자에게. 더 나은 솔루션을 제공 할 것을 요청합니다. 그 외에도 다운 투표에 대한 이유는 좋을 것입니다.
Tomalak

1
@Rocket : 잘못되었습니다. a) eval()유일한 방법입니다. b) 나는 OP에 대해주의했다. c) Matthew Crumley의 답변을보고 더 나은 설명을 생각하십시오. (오, d) 성명서 eval()가 나쁘다는 것은이 일반화 된 형태로 말도 안됩니다.)
Tomalak

2
@Rocket : 아, 바로 오해. 죄송합니다. 다운 투표는 귀하의 것이라고 생각했습니다. :)
Tomalak

1
@ kuboslav : 잘 작동합니다. 테스트 했습니까? 그는 eval("var x = " + str + ";")완전히 유효한 JS입니다. 당신은 할 필요가 없습니다 var x = ({a:12}).
로켓 Hazmat

2
@kuboslav IE7에는 기본 JSON 지원이 없기 때문에 IE7에서는 작동하지 않습니다. 사용하자마자 작동하기 시작합니다 json2.js. 그렇게 행복하지 마십시오.
Tomalak

4

면책 조항 : 집에서 또는 다른 개발자가 당신을 심각하게 생각하는 것을 요구하지 마십시오 :

JSON.stringify(eval('(' + str + ')'));

나는 그것을했다.
eval은 당신에게 나쁜 것입니다. 위에서 언급했듯이 구형 브라우저 (IE7 이하)에는 Crockford의 JSON shim을 사용하십시오.

이 방법을 사용하려면 문자열이 유효한 javascript 이어야하며 , 이는 javascript 객체로 변환 된 다음 JSON으로 직렬화 될 수 있습니다.

편집 : 로켓이 제안한대로 수정되었습니다.


JSON.stringify(eval('('+str+')'));내가 condone하지 않아야 eval하지만 그의 문자열은 유효한 JSON JSON.parse이 아니므로 작동하지 않습니다.
로켓 Hazmat

4

이 오래된 스레드에 관심이있는 사람에게 답을했습니다.

jQuery 플러그인 및 데모HTML5 data- * parser 를 만들었습니다.이 형식 은 잘못된 JSON 문자열을 사용하지 않고 JavaScript 객체로 변환합니다 .eval()

다음 HTML5 data- * 속성을 전달할 수 있습니다.

<div data-object='{"hello":"world"}'></div>
<div data-object="{hello:'world'}"></div>
<div data-object="hello:world"></div>

객체로 :

{
    hello: "world"
}


2

이 위업을 달성하는 훨씬 간단한 방법이 있습니다. 더미 요소의 onclick 속성을 가로 채서 문자열을 JavaScript 객체로 강제로 반환하면됩니다.

var jsonify = (function(div){
  return function(json){
    div.setAttribute('onclick', 'this.__json__ = ' + json);
    div.click();
    return div.__json__;
  }
})(document.createElement('div'));

// Let's say you had a string like '{ one: 1 }' (malformed, a key without quotes)
// jsonify('{ one: 1 }') will output a good ol' JS object ;)

데모는 다음과 같습니다. http://codepen.io/csuwldcat/pen/dfzsu (콘솔 열기)


2

결과에 "eval", JSON.stringify, JSON.parse를 사용해야합니다.

 var errorString= "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
 var jsonValidString = JSON.stringify(eval("(" + errorString+ ")"));
 var JSONObj=JSON.parse(jsonValidString);

여기에 이미지 설명을 입력하십시오


1

괄호가 없으면 eval중괄호 안의 코드가 명령 블록으로 간주 되므로 둥근 괄호를 작성해야 합니다.

var i = eval("({ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] })");

1

가장 안전하고 안전한 방법은 JSON5 – JSON for Humans 입니다. 해당 유스 케이스를 위해 특별히 작성되었습니다.

const result = JSON5.parse("{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }");

console.log(JSON.stringify(result));
<script src="https://cdnjs.cloudflare.com/ajax/libs/json5/0.5.1/json5.min.js"></script>


1

new Function ()을 사용하는 것이 eval보다 낫지 만 안전한 입력에서만 사용해야합니다.

const parseJSON = obj => Function('"use strict";return (' + obj + ')')();

console.log(parseJSON("{a:(4-1), b:function(){}, c:new Date()}"))
// outputs: Object { a: 3, b: b(), c: Date 2019-06-05T09:55:11.777Z }

출처 : MDN , 2ality


0

위의 간단한 예에서는 2 개의 간단한 정규식 대체를 사용하여이 작업을 수행 할 수 있습니다.

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
str.replace(/(\w+):/g, '"$1":').replace(/'/g, '"');
 => '{ "hello": "world", "places": ["Africa", "America", "Asia", "Australia"] }'

큰주의 사항 :이 순진한 접근법은 객체에 '또는 :문자를 포함하는 문자열이 없다고 가정합니다 . 예를 들어, 다음 객체 문자열을 사용하지 않고 다음 객체 문자열을 JSON으로 변환하는 좋은 방법을 생각할 수 없습니다 eval.

"{ hello: 'world', places: [\"America: The Progressive's Nightmare\"] }"

0

그것의 단점을 위해, 당신은 통해 문자열을 변환 할 수 있습니다 babel-standalone

var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";

function toJSON() {
  return {
    visitor: {
      Identifier(path) {
        path.node.name = '"' + path.node.name + '"'
      },
      StringLiteral(path) {
        delete path.node.extra
      }
    }
  }
}
Babel.registerPlugin('toJSON', toJSON);
var parsed = Babel.transform('(' + str + ')', {
  plugins: ['toJSON']
});
var json = parsed.code.slice(1, -2)
console.log(JSON.parse(json))
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>


0

var str = "{hello : 'world', 장소 : [ 'Africa', 'America', 'Asia', 'Australia']}"var fStr = str .replace (/ ([Az] *) (:) / g, ' "$ 1":') .replace (/ '/ g, "\" ")

console.log (JSON.parse (fStr))여기에 이미지 설명을 입력하십시오

죄송합니다. 전화를 받고 있습니다. 여기 사진이 있습니다.


0

하나의 정규 표현식이 있고 eval을 사용하지 않는 솔루션 :

str.replace(/([\s\S]*?)(')(.+?)(')([\s\S]*?)/g, "$1\"$3\"$5")

이것은 여러 줄과 작은 따옴표 'string'의 가능한 모든 발생 (/ g 플래그)을 큰 따옴표 "string"으로 대체해야한다고 생각합니다.


0
var str = "{ hello: 'world', places: ['Africa', 'America', 'Asia', 'Australia'] }";
var json = JSON.stringify(eval("(" + str + ")"));

-1

어쩌면 이것을 시도해야 할 수도 있습니다.

str = jQuery.parseJSON(str)

질문이 "또는 jQuery"로 지정되었으며 사용 가능한 경우 완벽한 솔루션입니다.
Ecropolis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.