"eval ()"및 "JSON.parse ()"기술은 상호 배타적 인 형식을 사용합니다.
- "eval ()"괄호가 필요합니다 .
- "JSON.parse ()"괄호는 금지되어 있습니다.
"eval"형식을 생성하는 "stringify ()"함수가 있습니다. ajax의 경우 JSON 형식 만 사용해야합니다.
"eval"은 전체 JavaScript 언어를 통합하지만 JSON은 언어의 일부만 사용합니다. "eval"이 인식해야하는 JavaScript 언어의 구조 중에는 "Block 문"(일명 "복합 문")이 있습니다 . 내부에 일부 명령문이있는 쌍 또는 중괄호 "{}"입니다. 그러나 중괄호는 객체 리터럴의 구문에도 사용됩니다. 해석은 코드가 나타나는 컨텍스트에 따라 다릅니다. 어떤 것이 당신에게 객체 리터럴처럼 보일 수 있지만 "eval"은 그것을 복합 문으로 볼 것입니다.
JavaScript 언어에서 객체 리터럴은 할당 오른쪽에 나타납니다.
var myObj = { ...some..code..here... };
객체 리터럴은 자체적으로 발생하지 않습니다.
{ ...some..code..here... }
2008 년에 질문했던 OP의 원래 질문으로 돌아가서 그는 "eval ()"에서 다음이 실패한 이유를 물었습니다.
{ title: "One", key: "1" }
대답은 그것이 복합 문처럼 보인다는 것입니다. 객체로 변환하려면 복합 문이 불가능한 컨텍스트에 넣어야합니다. 주위에 괄호를 넣어서
( { title: "One", key: "1" } )
OP는 또한 유사한 진술 이 성공적으로 평가 된 이유를 물었습니다 .
[ { title: "One", key: "1" }, { title: "Two", key: "2" } ]
동일한 대답이 적용됩니다. 중괄호는 복합 명령문이 불가능한 컨텍스트에 있습니다. 이것은 배열 컨텍스트 인 " [...]
"이며 배열은 객체를 포함 할 수 있지만 명령문은 포함 할 수 없습니다.
"eval ()"과 달리 JSON은 그 기능이 매우 제한적입니다. 제한은 의도적입니다. JSON 디자이너는 할당의 오른쪽에 나타날 수있는 구문 만 사용하여 JavaScript의 최소한의 하위 집합을 의도했습니다. 따라서 JSON에서 올바르게 구문 분석하는 코드가 있다면 ...
var myVar = JSON.parse("...some...code...here...");
... 이는 이와 같이 할당의 오른쪽에서도 합법적으로 구문 분석 할 것임을 의미합니다.
var myVar = ...some..code..here... ;
그러나 이것이 JSON에 대한 유일한 제한은 아닙니다. JSON에 대한 BNF 언어 사양은 매우 간단합니다. 예를 들어, 문자열을 나타 내기 위해 작은 따옴표를 사용할 수 없으며 (JavaScript 및 Perl처럼) 단일 문자를 바이트로 표현하는 방법이 없습니다 ( 'C'처럼). 불행히도 주석도 허용하지 않습니다 (구성 파일을 만들 때 정말 좋을 것입니다). 이러한 모든 제한의 장점은 JSON 구문 분석이 빠르고 코드 삽입 (보안 위협)의 기회를 제공하지 않는다는 것입니다.
이러한 제한으로 인해 JSON은 괄호를 사용하지 않습니다. 따라서 JSON 문자열의 괄호는 잘못된 문자입니다.
다음과 같은 이유로 항상 ajax와 함께 JSON 형식을 사용합니다.
- 일반적인 ajax 파이프 라인은 JSON 용으로 구성됩니다.
- "eval ()"의 사용은 보안 위험으로 비판 될 것입니다.
ajax 파이프 라인의 예로 Node 서버와 jQuery 클라이언트를 포함하는 프로그램을 고려하십시오. 클라이언트 프로그램은 형식이있는 jQuery 호출을 사용합니다 $.ajax({dataType:'json',...etc.});
. JQuery는 나중에 사용하기 위해 jqXHR 객체를 생성 한 다음 관련 요청을 패키징하고 보냅니다. 서버는 요청을 수락하고 처리 한 다음 응답 할 준비가됩니다. 서버 프로그램은 res.json(data)
응답을 패키징하고 전송하기 위해 메서드 를 호출합니다 . 클라이언트 측으로 돌아가서 jQuery는 응답을 수락하고 연관된 jqXHR 객체를 참조하고 JSON 형식 데이터를 처리합니다. 이 모든 것이 수동 데이터 변환없이 작동합니다. 응답에는 Node 서버에서 JSON.stringify ()에 대한 명시 적 호출과 클라이언트에서 JSON.parse ()에 대한 명시 적 호출이 포함되지 않습니다. 그게 모두 당신을 위해 처리됩니다.
"eval"의 사용은 코드 삽입 보안 위험과 관련이 있습니다. 일어날 수있는 방법이 없다고 생각할 수도 있지만 해커는 상당히 창의적 일 수 있습니다. 또한 "eval"은 Javascript 최적화에 문제가 있습니다.
"stringify ()"함수를 사용하는 경우 해당 이름을 가진 일부 함수는 JSON이 아닌 "eval"과 호환되는 문자열을 생성한다는 점에 유의하십시오. 예를 들어, Node에서 다음은 "eval"호환 형식으로 문자열을 생성하는 함수를 제공합니다.
var stringify = require('node-stringify');
이것은 유용 할 수 있지만 특별한 필요가 없다면 아마도 원하는 것이 아닐 것입니다.