HTML 속성에 JSON을 저장하는 가장 좋은 방법은 무엇입니까?


112

HTML 요소의 속성에 JSON 개체를 넣어야합니다.

  1. HTML은 유효성을 검사 할 필요가 없습니다.

    Quentin의 답변 : 유효한 HTML5 인 속성에 JSON을 저장합니다data-* .

  2. JSON 객체는 모든 크기가 될 수 있습니다.

    답변 : Maiku Mori : HTML 속성의 제한은 잠재적으로 65536 자 입니다.

  3. JSON에 특수 문자가 포함되어 있으면 어떻게됩니까? 예 : {foo: '<"bar/>'}

    Quentin에 의해 답변 됨 : 일반적인 규칙에 따라 JSON 문자열을 속성에 넣기 전에 인코딩하십시오. PHP를 들어, 사용 기능 . htmlentities()


편집-PHP 및 jQuery를 사용하는 예제 솔루션

HTML 속성에 JSON 쓰기 :

<?php
    $data = array(
        '1' => 'test',
        'foo' => '<"bar/>'
    );
    $json = json_encode($data);
?>

<a href="#" data-json="<?php echo htmlentities($json, ENT_QUOTES, 'UTF-8'); ?>">CLICK ME</a>

jQuery를 사용하여 JSON 검색 :

$('a').click(function() {

    // Read the contents of the attribute (returns a string)
    var data = $(this).data('json');

    // Parse the string back into a proper JSON object
    var json = $.parseJSON($(this).data('json'));

    // Object now available
    console.log(json.foo);

});

아마도 이것이 최선이 아니라고 확신하므로 이유를 설명하고 다른 해결책을 요청해야합니다. 데이터 속성을 사용할 수는 있지만 "거대한"텍스트를 저장할 수 있는지 확실하지 않습니다. 특수 문자의 경우 텍스트를 인코딩 (escape () 및 unescape ()) 할 수 있습니다.
Maiku Mori 2011 년

그래 제한은 65536 개 문자입니다 ( stackoverflow.com/questions/2752457/... )
Maiku 모리

1
Btw, 당신의 속성 이름이 data-json당신이 사용해야 $(this).data('json')한다면 jQuery는 그 부분을 다루었습니다.
Ciantic 2013

참고로 데이터 접미사 이름을 json으로 지정할 필요는 없습니다. data-custom_attribute에 유효한 json을 넣으면 jQuery에서 제대로 작동합니다.
Garet Claborn 2014-04-05

중괄호 시퀀스를 수정하십시오)}; =>});
MotsManish 2016-06-09

답변:


41

HTML은 유효성을 검사 할 필요가 없습니다.

왜 안돼? 검증은 많은 실수를 포착하는 정말 쉬운 QA입니다. HTML 5 data-*속성을 사용하십시오 .

JSON 객체는 모든 크기 (즉, 거대)가 될 수 있습니다.

속성 크기에 대한 브라우저 제한에 대한 문서를 보지 못했습니다.

그들과 마주 치면 데이터를 <script>. 객체를 정의하고 요소 id를 해당 객체의 속성 이름에 매핑 합니다.

JSON에 특수 문자가 포함되어 있으면 어떻게됩니까? (예 : {테스트 : '< "myString />'})

신뢰할 수없는 데이터를 속성 값에 포함하는 일반적인 규칙을 따르십시오. 사용 &amp;&quot;(큰 따옴표의 속성 값을 포장하는 경우) 또는 &#x27;(만약 당신이있는 거 포장 따옴표 속성 값).

그러나 이는 JSON이 아닙니다 (속성 이름은 문자열이고 문자열은 큰 따옴표로만 구분되어야 함).


5
그래서 htmlentities($json)내가 그것을 HTML 속성에 넣기 전에 해야한다는 말입니까? 그런 다음 jQuery에서 읽고 싶을 때 어떻게 디코딩합니까? 그런 다음 PHP에서와 같은 방식으로 jQuery를 사용하여 어떻게 다시 작성합니까?
BadHorsie 2011 년

6
그래서 당신은 내가 그것을 HTML 속성에 넣기 전에 html_encode ($ json)을해야한다고 말하는 건가요? — PHP를 사용하는 경우 작동합니다. 그런 다음 jQuery에서 읽고 싶을 때 어떻게 디코딩합니까? — 속성에서 디코딩 하시겠습니까? 브라우저는 HTML을 DOM으로 구문 분석 할 때이를 수행합니다. 그런 다음 PHP에서와 같은 방식으로 jQuery를 사용하여 어떻게 다시 작성합니까? — 원시 HTML을 생성하지 않고 DOM 노드의 속성을 설정하면 브라우저가 처리합니다.
Quentin 2011 년

1
현재 내 브라우저가 현재 Chrome에서 디코딩하지 않는 문제가 있으며 JSON을 구문 분석 할 때 모든 HTML 엔티티가 있고 실패합니다.
Bradley Weston

스크립트 태그에 넣으면 스크립트 태그의 특수 처리로 인해 다르게 이스케이프해야합니다. 예를 들어 </ script>가있는 값은 스크립트 태그를 끝냅니다.
Dobes Vandermeer

16

어디에 두느냐에 따라

  • A의 <div>당신이 묻는대로, 당신은 JSON은 태그, HTML 주석, 포함 된 문서 타입을 시작할 수 HTML 스페셜을 포함하지 않는 것을 확인해야합니다, 등 당신은 적어도 탈출해야 <하고, &원래의 캐릭터가하지 않는 방식으로 이스케이프 된 시퀀스에 나타납니다.
  • 에서 <script>요소 당신은 JSON이 종료 태그가 포함되어 있지 않은지 확인해야합니다 </script>: 또는 탈출 텍스트 경계 <!--또는 -->.
  • 이벤트 처리기에서 JSON이 HTML 엔터티처럼 보이고 속성 경계 ( "또는 ')를 깨지 않는 항목이 있어도 의미를 유지하는지 확인해야합니다 .

처음 두 경우 (및 이전 JSON 파서의 경우)의 경우 U + 2028 및 U + 2029는 JSON에서 인코딩되지 않은 문자열에서 허용 되더라도 JavaScript에서 개행 문자이므로 인코딩해야합니다.

정확성을 위해 이스케이프 \및 JSON 인용 문자 가 필요 하며 항상 NUL을 인코딩하는 것은 나쁜 생각이 아닙니다.

HTML이 콘텐츠 인코딩없이 제공 될 수있는 경우 UTF-7 공격+ 을 방지하기 위해 인코딩해야합니다 .

어쨌든 다음 이스케이프 테이블이 작동합니다.

  • NUL-> \u0000
  • CR-> \n또는\u000a
  • LF-> \r또는\u000d
  • " -> \u0022
  • & -> \u0026
  • ' -> \u0027
  • + -> \u002b
  • /-> \/또는\u002f
  • < -> \u003c
  • > -> \u003e
  • \-> \\또는\u005c
  • U + 2028- >\u2028
  • U + 2029-> \u2029

따라서 Hello, <World>!끝에 개행 문자 가있는 텍스트의 JSON 문자열 값은 "Hello, \u003cWorld\u003e!\r\n".


1
return (input.replace(/([\s"'& + \ / \\ <> \ u2028 \ u2029 \ u0000]) / g, (일치, p1) => {return \\u${p1.codePointAt(0).toString(16).padStart(4, 0)}; }));`
Denis Giffeler

14

당신이 그것을 할 수있는 또 다른 방법은 - 내부 JSON 데이터를 넣어 <script>태그,은 불가능 type="text/javascript"하지만, 함께 type="text/bootstrap"또는 type="text/json"유형, 자바 스크립트 실행을 방지하기 위해.

그런 다음 프로그램의 어떤 위치에서 다음과 같은 방법으로 요청할 수 있습니다.

function getData(key) {
  try {
    return JSON.parse($('script[type="text/json"]#' + key).text());
  } catch (err) { // if we have not valid json or dont have it
    return null;
  } 
}

서버 측에서는 다음과 같이 할 수 있습니다 (이 예제는 php 및 twig ).

<script id="my_model" type="text/json">
  {{ my_model|json_encode()|raw }}
</script>

1
JSON의 경우 "application / json"스크립트 유형을 사용하십시오. 또한 장기적으로 최상위 수준을 대상으로하는 것도 좋습니다.
OIS

1
이것은 op의 질문에 직접 답하지는 않지만 여전히 나에게 매우 도움이되었습니다. 내가 저장하는 데이터는 특정 요소가 아닌 전체 페이지에 적용되므로 요소 속성은 실제로 작동하지 않습니다. 데이터가 클 수 있음). <script type="application/json" id="MyData"></script>작품에 완벽하게 저장합니다 . 그런 다음 ActiveWAFL / DblEj를 사용하여 다음과 같이 조회 할 수 있습니다 document.GetData("#MyData")..
Evan de la Cruz

2
이 답변에는 거짓 / 위험한 정보가 포함되어 있습니다! 스크립트 유형을 변경해도 </ script> 태그 감지는 수정되지 않습니다. 시도해보십시오 :<script type="application/json" id="MyData"> "abc</script><script>alert()</script>" </script>
hyperknot

12

또 다른 옵션은 JSON 문자열을 base64로 인코딩하고 자바 스크립트에서 사용해야하는 경우 atob()함수로 디코딩하는 것입니다 .

var data = JSON.parse(atob(base64EncodedJSON));

감사합니다 atob. 나는 그것을 전혀 몰랐다!
Ifedi Okonkwo

3
주의-JSON에 라틴어가 아닌 문자가 포함 된 경우 작동하지 않습니다.
Realexer jul.

5

knockoutjs를 사용할 수 있습니다.

<p>First name: <strong data-bind="text: firstName" >todo</strong></p>
<p>Last name: <strong data-bind="text: lastName">todo</strong></p>

knockout.js

// This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
function AppViewModel() {
    this.firstName = "Jayson";
    this.lastName = "Monterroso";
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());

산출

이름 : Jayson 성 : Monterroso

이것을 확인하십시오 : http://learn.knockoutjs.com/


2

여기에 멋진 것은 없습니다. PHP에서 htmlspecialchars특수 문자가 HTML로 해석 될 수 없도록 JSON 문자열을 실행 합니다. 자바 스크립트에서는 이스케이프가 필요하지 않습니다. 속성을 설정하기 만하면됩니다.


2

간단한 JSON 객체의 경우 아래 코드가 작동합니다.

인코딩 :

var jsonObject = { numCells: 5, cellWidth: 1242 };
var attributeString = escape(JSON.stringify(jsonObject));

풀다:

var jsonString = unescape(attributeString);
var jsonObject = JSON.parse(jsonString);

1

당신이 할 수있는 일은 당신의 요소 주위에 cdata 를 사용하는 것입니다.

<![CDATA[  <div class='log' mydata='${aL.logData}'>${aL.logMessage}</div>     ]]>  

여기서 mydata는 원시 json 문자열입니다. 이것이 당신과 다른 사람들에게 도움이되기를 바랍니다.


이 솔루션은 어떻게 작동합니까? ">mydata 와 같은 것을 저장하려면 어떻게해야 합니까?
Martin Pecka 2014

1
문자열에 "]]>"가 포함 된 경우
Dobes Vandermeer

1

사용할 수있는 또 다른 생각은 JSON 데이터를 속성에 base64 문자열로 저장 한 다음이를 사용 window.atob하거나 window.btoa사용 가능한 JSON 데이터로 복원하는 것입니다.

<?php
$json = array("data"=>"Some json data thing");
echo "<div data-json=\"".base64_encode(json_encode($json))."\"></div>";
?>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.