2012-02-16 2 views
79

나는이 같은 DOM에서 임의 JSON을 내장 생각 해요 :임의의 JSON을 DOM에 임베드하는 가장 좋은 방법은 무엇입니까?

<script type="application/json" id="stuff"> 
    { 
     "unicorns": "awesome", 
     "abc": [1, 2, 3] 
    } 
</script> 

이 하나가 자바 스크립트 템플릿 엔진 나중에 사용하기 위해 DOM에서 임의의 HTML 템플릿을 저장할 수있는 방법과 유사하다. 이 경우, 우리는 나중에 JSON을 검색 할 수 있고 그것을 구문 분석 :

var stuff = JSON.parse(document.getElementById('stuff').innerHTML); 

This works하지만 가장 좋은 방법은? 이것이 모범 사례 또는 표준을 위반합니까?

참고 : DOM에 JSON을 저장하는 대안을 찾고 있지 않습니다. 이미 가지고있는 특정 문제에 대한 최선의 해결책이라고 판단했습니다. 나는 그것을하기위한 최선의 방법을 찾고 있습니다.

+1

? DOM에 저장하는 것은 내가 원하는 것입니다. – Krizz

+0

@Krizz, 그것은 나중에 복잡한에 의해 처리되는 정적 문서의 일부가 필요한 이유

var text = document.querySelector('#init_data').textContent; var json = JSON.parse(text); console.log(json); // {html: "<script>alert("XSS!");</script>"} 

+0

@Krizz 비슷한 문제가있었습니다. AJAX 요청없이 각 사용자마다 다른 사이트에 데이터를 저장하려고했습니다. 그래서 컨테이너에 약간의 PHP를 임베드했는데 자바 스크립트에서 데이터를 얻기 위해 위에있는 것과 비슷한 것을했습니다. –

답변

61

나는 원래의 방법이 최고라고 생각합니다. HTML5의 사양도 주소이 사용 :

(스크립트 반대) 데이터 블록을 포함하는 데 사용하는 경우

"데이터 이 포함되어야한다 인라인, 데이터의 형식이 type 속성을 사용하여 부여해야합니다, src 속성을 지정하지 않아야하며 스크립트 요소의 내용이 사용 된 형식에 대해 정의 된 요구 사항을 준수해야합니다. "

는 여기에 읽기 : http://dev.w3.org/html5/spec/Overview.html#the-script-element

당신은 정확하게 일을했습니다. 사랑하지 않는 것은 무엇입니까? 속성 데이터에는 필요에 따라 문자 인코딩이 없습니다. 원하는 경우 서식을 지정할 수 있습니다. 표현력이 뛰어나고 의도 한 용도가 분명합니다. 해킹처럼 느껴지지 않습니다 (예 : CSS를 사용하여 '이동 통신사'요소가 숨겨 짐). 그것은 완벽하게 유효합니다.

+2

감사합니다. 스펙의 견적은 나를 확신시켰다. –

+15

JSON 개체를 먼저 확인하고 위생 처리하는 경우에만 완벽하게 유효합니다. 사용자가 보낸 데이터를 포함 할 수 없습니다. 질문에 대한 내 의견을 참조하십시오. – silviot

+1

추가 궁금한 점 : 그것을 넣을 좋은 장소는 무엇입니까? 머리 또는 몸, 위 또는 아래? – challet

18

일반적인 지침에 따라 HTML5 data attributes을 대신 사용해 보겠습니다. 유효한 JSON을 넣는 것을 막을 수있는 방법은 없습니다. 예 :

<div id="mydiv" data-unicorns='{"unicorns":"awesome", "abc":[1,2,3]}' class="hidden"></div> 

당신이 그 때처럼 쉽게 검색, jQuery를 사용하는 경우 :

var stuff = JSON.parse($('#mydiv').attr('data-unicorns')); 
+1

감각을 만드십시오. 키 이름에 대해 작은 따옴표를 사용하면 'JSON.parse'가 작동하지 않습니다 (적어도 기본 Chrome JSON.parse는 작동하지 않음). JSON 사양에는 큰 따옴표가 필요합니다. 하지만 '<unicorns> : ...'과 같은 엔티티를 사용하여 수정하기는 쉽습니다. –

+4

하나의 질문 : HTML 5의 속성 길이에는 제한이 있습니까? –

+0

네, 그게 효과가 있습니다. HTML을 작은 따옴표로 사용하고 JSON 데이터에 double을 사용하도록 전환 할 수도 있습니다. –

5

내가 함수 콜백 JSONP의 (종류 인라인 스크립트로 JSON을 넣어 좋을 것) :

<script> 
someCallback({ 
    "unicorns": "awesome", 
    "abc": [1, 2, 3] 
}); 
</script> 

실행중인 스크립트가 당신이 추가 식별자 인수 가능성이 어딘가를 저장할 수있는 문서 후에로드 된 경우 : someCallback("stuff", { ... });

+0

제안 해 주셔서 감사합니다.하지만 그건 내 목적에 맞지 않습니다. –

+0

@BenLee 콜백 함수를 정의해야한다는 단점이 있지만 잘 작동해야합니다. 다른 제안 된 솔루션은 특수 HTML 문자 (예 : &)와 따옴표가 JSON에있는 경우이를 구분합니다. – copy

+0

데이터를 찾기 위해 dom 쿼리가 필요 없기 때문에 느낌이 좋아집니다. – Jaseem

2

JSON 데이터를 외부 .json 파일에 보관 한 다음 Ajax를 통해 해당 파일을 검색하는 것이 좋습니다. CSS와 JavaScript 코드를 웹 페이지 (인라인)에 넣지 않으므로 JSON을 사용하면 어떨까요?

+9

일반적으로 CSS와 자바 스크립트는 다른 페이지와 공유되기 때문에 웹 페이지에 삽입하지 마십시오. 문제의 데이터가이 컨텍스트에 대해 명시 적으로 서버에 의해 생성되는 경우 캐싱 할 수없는 것에 대한 다른 요청을 시작하는 것보다 훨씬 효율적입니다. –

+0

레거시 시스템에 대한 업데이트를 제대로 작성하지 않았기 때문에 전체 시스템을 재 설계하지 않고 한 부분 만 수정해야합니다. JSON을 DOM에 저장하는 것이이 부분을 수정하는 가장 좋은 방법입니다. 또한 @jamietre가 말한 것에 동의합니다. –

+0

@jamietre OP는이 JSON 문자열이 나중에 필요하다는 것을 명시했다. * 나중에 *. 문제는 그것이 항상 필요하거나 경우에 따라서 만 필요한 것입니다. 어떤 경우에만 필요하다면 외부 파일에 넣고 조건부로로드하는 것이 좋습니다. –

10

스크립트 태그에 json을 포함시키는이 방법은 잠재적 인 보안 문제가 있습니다. json 데이터가 사용자 입력에서 비롯되었다고 가정하면 실제로 스크립트 태그에서 벗어나 DOM에 직접 주입 할 데이터 멤버를 만들 수 있습니다.여기를 참조하십시오 :

http://jsfiddle.net/YmhZv/1/

여기/인코딩을 탈출 주변 단지 방법이 주입

<script type="application/json" id="stuff"> 
{ 
    "unicorns": "awesome", 
    "abc": [1, 2, 3], 
    "badentry": "blah </script><div id='baddiv'>I should not exist.</div><script type="application/json" id='stuff'> ", 
} 
</script> 

에게 있습니다.

+5

사실이지만이 방법의 보안 결함은 아닙니다. 사용자 입력에서 비롯된 어떤 것을 페이지에 넣는다면 탈출에 많은 노력을 기울여야합니다. 이 방법은 사용자 입력과 관련하여 일반적인 사전 예방 조치를 취하는 한 여전히 유효합니다. –

+0

JSON은 HTML의 일부가 아니므로 HTML 파서 만 계속 진행됩니다. JSON이 텍스트 단락이나 div 요소의 일부일 때와 같습니다. 프로그램에서 HTML을 이스케이프 처리합니다. 또한 슬래시를 벗어날 수도 있습니다. JSON은 이것을 요구하지 않지만 불필요한 슬래시를 허용합니다. 퍼가기를 안전하게하기 위해 그녀를 사용할 수 있습니다. PHP의 json_encode는 기본적으로이 작업을 수행합니다. – Krinkle

0

OWASP의 XSS 예방 치트 시트에 Rule #3.1을 참조하십시오.

{ 
    "html": "<script>alert(\"XSS!\");</script>" 
} 

는 HTML의 숨겨진 <div> 만들기 :

는 HTML에서이 JSON을 포함 할 말. 다음으로, 안전하지 않은 개체를 인코딩하여 JSON을 탈출 (예를 들어, &, <,>, ", ', 그리고, /) 및 요소 내부에 넣어.

<div id="init_data" style="display:none"> 
     {&#34;html&#34;:&#34;&lt;script&gt;alert(\&#34;XSS!\&#34;);&lt;/script&gt;&#34;} 
</div> 

을 이제 textContent의를 읽어 액세스 할 수 있습니다 자바 스크립트를 사용하여 분석 요소 :

당신이 자바 스크립트에서`var`로하지 않습니다