JSON 결과에서 함수를 정의하는 것이 유효합니까?


98

웹 사이트의 JSON 응답에 다음이 포함되었습니다 (... 컨텍스트를 위해 추가됨).

{..., now:function(){return(new Date).getTime()}, ...}

JSON에 익명 함수를 추가하는 것이 유효합니까? '시간'에 액세스 할 때마다 다른 값이 반환 될 것으로 예상합니다.


JSON이 브라우저에서 성공적으로 구문 분석 되었습니까? 그렇다면 그렇습니다 (그 점에서).
harschware

7
@harschware-JSON이 javascript와 관련된 경우에만 해당됩니다. 언어 독립적 인 데이터 직렬화 형식으로서 이는 거짓이며 걸어가는 데 문제가되는 길입니다.
jsoverson 2010 년

@jsoverson-동의합니다. 아래 내 대답을 참조하십시오.
harschware

1
이 질문에 쉽게 답할 수 있습니다. 웹 키트 검사기를 열고 다음을 실행하십시오 JSON.parse('{now:function(){return(new Date).getTime()}').. 검사관은 다음과 같이 말합니다. JSON 사양을Uncaught SyntaxError: Unexpected token n 훑어 보면 이를 확인할 수 있습니다. '가치'섹션에 중점을 둡니다.
Mark E. Haase

답변:


103

아니.

JSON은 순전히 데이터 설명 언어를 의미합니다. http://www.json.org 에서 언급했듯이 "경량 데이터 교환 형식"입니다. -프로그래밍 언어가 아닙니다.

http://en.wikipedia.org/wiki/JSON , 지원하는 '기본 유형'입니다 :

  • 숫자 (정수, 실수 또는 부동 소수점)
  • 문자열 (백 슬래시 이스케이프가있는 큰 따옴표 유니 코드)
  • 부울 (true 및 false)
  • 배열 (순서있는 값 시퀀스, 쉼표로 구분되고 대괄호로 묶임)
  • 객체 (키 : 값 쌍 모음, 쉼표로 구분되고 중괄호로 묶임)
  • null

2
@Dr. Zim, 아니, 내가하는 일을 null과 비교하는 것은 이것이하는 일입니다. 이것은 a==null?1:a.toString()==""a = null이면 1 / true를 반환하고, ""이면 빈 문자열을 의미하는 경우 1 / true를 얻습니다. null 또는 ""가 아니라면 0 / false를 반환합니다. []와 함께 작동하도록 더 복제 할 수 있으며 {}는 단순히 ?1:a==[]?1:a.toString()=={}.toString();이전 스 니펫에 추가 하기 만하면 됩니다. 이 기능이 도움이 될 것입니다. isnull=(function(a){return (a==null?1:a.toString()==""?1:a==[]?1:a.toString()=={}.toString())?true:false})내가 사용하는 것 ?1:0대신 ?true:false하지만, (참 / 거짓)
JamesM - SiteGen

10
동시에 함수도 데이터입니다.
argyle

2
JSON을 사용하여 "추가 데이터"를 가져 오는 방법을 찾는 동안 여기에 도착했습니다. 클라이언트가 다음에 호출 할 REST 정도의 API에 대해 걱정하지 않고 클라이언트 (서버에서)에게 추가 데이터를 가져 오는 방법을 알려주는 것이 좋습니다.
Ravindranath Akila

3
@RavindranathAkila REST는 가능한 다음 API 호출이 호출에 노출됨을 의미합니다. 즉, REST 요청을 통해 수행 할 수있는 향후 요청을 알려줍니다 (애플리케이션 결정 논리 및 데이터에 따라). 이에 대한 완벽한 예는 데이터 요소가 반환되지만 일부는 다른 API 요청 리소스로 연결되는 Github API입니다.
Jens A. Koch

1
@ Jens-AndréKoch 감사합니다! 그것을 확인합니다
Ravindranath Akila에게

16

문제는 데이터 정의 언어 인 JSON이 JSON에서 JavaScript Object Notation으로 발전했다는 것입니다. Javascript는 JSON에서 eval을 지원하므로 JSON 코드를 JSON 안에 넣는 것이 합법적입니다 (해당 사용 사례에서). JSON을 사용하여 데이터를 원격으로 전달하는 경우 클라이언트-서버 상호 작용을 잘 모델링하지 않았을 수 있기 때문에 JSON에 메서드를 넣는 것이 좋지 않다고 말합니다. 또한 JSON을 데이터 설명 언어로 사용하려는 경우 일부 JSON 파서가 데이터 설명 만 염두에두고 작성되었으며 구조에서 메서드 정의를 지원하지 않을 수 있기 때문에 메서드를 포함하면 문제가 발생할 수 있습니다.

Wikipedia JSON 항목 은 보안 문제를 언급하면서 JSON에 메서드를 포함하지 않는 좋은 사례입니다.

텍스트의 소스를 절대적으로 신뢰하지 않고 엄격하게 JSON을 준수하지 않는 텍스트를 구문 분석하고 허용해야하는 경우가 아니라면 eval ()을 피하고 대신 JSON.parse () 또는 다른 JSON 특정 구문 분석기를 사용해야합니다. JSON 파서는 JSON 텍스트 만 인식하고 악의적 인 JavaScript를 포함 할 수있는 다른 텍스트는 거부합니다. 네이티브 JSON 지원을 제공하는 브라우저에서 JSON 파서는 eval보다 훨씬 빠릅니다. 네이티브 JSON 지원은 다음 ECMAScript 표준에 포함될 것으로 예상됩니다.


2
JSON이라는 용어를 구어체로 사용할 수 있지만 공식적으로 "JSON"은 인코딩 할 함수 객체를 표시하지 않는 ECMA 표준입니다. "JSON"이라고 말할 때 어떤 기능을 언급하고 있는지 모호해서는 안됩니다 . 이것이 표준을 갖는 전체 요점 입니다.
Mark E. Haase

그것이 오늘 사실이라고 동의했습니다. 인용 할 소스는 없지만, JSON은 ECMA가 Javascript 게임에 도입되기 전에 만들어졌고 JSON이 표준 데이터 교환 형식이되기 전에 만들어진 용어라고 생각합니다. 따라서 '진화'라는 용어를 사용했습니다
harschware

@harschware RFC 4627에 따르면 JSON은 ECMA에서 만들어졌습니다.
Jenna Sloan

9

사양 중 하나를 인용 해 보겠습니다-http: //tools.ietf.org/html/rfc7159#section-12

자바 스크립트 객체 표기법 (JSON) 데이터 교환 형식 사양의 상태 :

JSON은 JavaScript의 하위 집합이지만 할당 및 호출을 제외합니다.

JSON의 구문은 JavaScript에서 차용되었으므로 해당 언어의 "eval ()"함수를 사용하여 JSON 텍스트를 구문 분석 할 수 있습니다. 텍스트
가 데이터 선언과 함께 실행 가능한 코드를 포함 할 수 있기 때문에
일반적으로 허용되지 않는 보안 위험을 구성합니다 . JSON 텍스트가 해당
언어의 구문을 따르는 다른 프로그래밍 언어에서 eval ()과 유사한 함수를 사용하는 경우에도 동일한 고려 사항이 적용됩니다 .

따라서 함수가 JSON 표준의 일부가 아닌 상태에 대한 모든 대답은 정확합니다.

공식적인 대답은 : 아니요, JSON 결과에서 함수를 정의하는 것은 유효하지 않습니다!


"코드는 데이터"이고 "데이터는 코드"이므로 대답은 예일 수 있습니다. JSON이 언어 독립적 인 데이터 직렬화 형식으로 사용 되더라도 다른 유형을 통한 "코드"터널링이 작동합니다.

JSON 문자열은 실행을 위해 클라이언트 측 브라우저에 JS 함수를 전달하는 데 사용될 수 있습니다.

[{"data":[["1","2"],["3","4"]],"aFunction":"function(){return \"foo bar\";}"}]

이것은 다음과 같은 질문으로 이어집니다 . " 문자열로 저장된 JavaScript 코드를 실행 하는 방법 ".

"eval () is evil"플래그를 올리고 그 옆에 "JSON을 통해 기능을 터널링하지 마십시오"플래그를 붙일 준비를하십시오.



4

아닙니다.

괜찮은 JSON 직렬 변환기를 사용하면 그런 함수를 직렬화 할 수 없습니다. 유효한 OBJECT이지만 유효한 JSON이 아닙니다. 해당 웹 사이트의 의도가 무엇이든 유효한 JSON을 보내지 않습니다.


2
저는 JSON-Lib를 사용하며 훌륭한 시리얼 라이저라고 생각합니다. 에서 [사용 페이지]에서 (json-lib.sourceforge.net/usage.html는) 당신은 잘 기능을 직렬화합니다 볼 수 있습니다
harschware

흥미 롭군요 ... 전에는 본 적이 없습니다. 사양은 아니지만 ( json.org 는 JSON이 언어 독립적이며 어떤 함수 정의가 아닌지 명시 적으로 명시합니다) 그럼에도 불구하고 흥미 롭습니다.
jvenema 2010 년

이 언어 독립적 있어야하지만 JSON 자바 스크립트 객체 표기법 음을 의미 있다는 재미 이상한 ..
네이트 - 윌킨스

3

JSON은 JavaScript 전용 데이터 구조가 아니기 때문에 명시 적으로 함수를 제외합니다 (이름에있는 JS에도 불구하고).


3

짧은 대답은 아니오입니다 .

JSON은 완전히 언어 독립적이지만 C, C ++, C #, Java, JavaScript, Perl, Python 등을 포함한 C 계열 언어의 프로그래머에게 익숙한 규칙을 사용하는 텍스트 형식입니다. 이러한 속성은 JSON을 이상적인 데이터 교환 언어로 만듭니다.

이유를보십시오.

브라우저와 서버간에 데이터를 교환 할 때 데이터는 텍스트 만 될 수 있습니다.

JSON은 텍스트이며 모든 JavaScript 객체를 JSON으로 변환하고 JSON을 서버로 보낼 수 있습니다.

서버에서받은 모든 JSON을 JavaScript 객체로 변환 할 수도 있습니다.

이렇게하면 복잡한 구문 분석 및 번역없이 데이터를 JavaScript 객체로 사용할 수 있습니다.

하지만 기다려 ...

함수를 저장하는 방법은 여전히 ​​있지만 널리 권장되지는 않지만 여전히 가능합니다.

우리는 string...를 저장할 수 있다고 말했습니다. 그러면 함수를 문자열로 변환하는 것은 어떻습니까?

const data = {func: '()=>"a FUNC"'};

그런 다음을 사용하여 데이터를 문자열 화 JSON.stringify(data)한 다음이를 사용 JSON.parse하여 구문 분석 할 수 있습니다 (이 단계가 필요한 경우).

그리고 eval 을 사용하여 문자열 함수를 실행합니다 (그 전에 eval을 널리 사용하지 않는 것이 좋습니다).

eval(data.func)(); //return "a FUNC"

0

NodeJS (commonJS 구문)를 사용하여 이러한 유형의 기능을 작동시킬 수 있었지만 원래는 외부 JS 파일 내부에 JSON 구조 만 있었지만 그 구조가 클래스에 더 가깝고 다음에서 결정할 수있는 메서드를 원했습니다. 런타임.

myJSON의 'Executor'선언은 필요하지 않습니다.

var myJSON = {
    "Hello": "World",
    "Executor": ""
}

module.exports = {
    init: () => { return { ...myJSON, "Executor": (first, last) => { return first + last } } }
}

-3

JSON의 함수 표현식은 완전히 가능합니다. 큰 따옴표로 묶는 것을 잊지 마십시오. 다음은 noSQL 데이터베이스 디자인에서 가져온 예입니다.

{
  "_id": "_design/testdb",
  "views": {
    "byName": {
      "map": "function(doc){if(doc.name){emit(doc.name,doc.code)}}"
    }
  }
}


문제는 문자열이 아닌 함수에 관한 것입니다. JSON은 문자열 값을 지원하지만 함수는 지원하지 않습니다. 참조 마이크의 답변을 자세한 내용은
jannis

@ jannis는 가능합니다. 같은 자체 호출 기능을 추가하면. 여기에있는 사람들은 분명히 답을 모릅니다.
Roj

-4

eval은 권장되지 않지만 작동합니다.

<!DOCTYPE html>
<html>
<body>

<h2>Convert a string written in JSON format, into a JavaScript function.</h2>

<p id="demo"></p>

<script>
    function test(val){return val + " it's OK;}
    var someVar = "yup";
    var myObj = { "func": "test(someVar);" };
    document.getElementById("demo").innerHTML = eval(myObj.func);
</script>

</body>
</html>

1
예제에서 HTML을 사용할 필요가 없기 때문에 투표가 거부되었습니다. 이것은 5 년 된 코딩 스타일이고, 누락 된 따옴표가 있으며, JSON 파일에는 함수가 포함되어 있지 않아야합니다. 아무 SQL 없다 DB,
마티 페르

-5

따옴표는 빼고 ...

var a = {"b":function(){alert('hello world');} };

a.b();

이것은 JavaScript이며 JSON에 대해 묻는 질문입니다.
Quentin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.