Лучшая практика для встраивания произвольного JSON в DOM?


Я думаю о внедрении произвольного JSON в DOM следующим образом:

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

это похоже на способ хранения произвольного шаблона HTML в DOM для последующего использования с шаблоном JavaScript. В этом случае мы могли бы позже получить JSON и проанализировать его с помощью:

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

это работает, но это лучший способ? Нарушает ли это какую-либо передовую практику или стандарт?

примечание: Я не ищу альтернатив храня JSON в DOM, я уже решил, что это лучшее решение для конкретной проблемы, с которой я сталкиваюсь. Я просто ищу лучший способ сделать это.

6 87

6 ответов:

Я думаю, что ваш оригинальный метод является лучшим. Спецификация HTML5 даже обращается к этому использованию:

" при использовании для включения блоков данных (в отличие от скриптов), данные должен быть встроен в строку, формат данных должен быть задан с помощью атрибут type, атрибут src не должны быть указаны, и содержимое элемента script должно соответствовать требованиям определено для используемого формата."

читать здесь: http://dev.w3.org/html5/spec/Overview.html#the-script-element

вы сделали именно это. Что такое не любить? Нет кодировки символов, как это необходимо с атрибутивными данными. Вы можете отформатировать его, если хотите. Это выразительно, и предполагаемое использование ясно. Это не похоже на взлом (например, как использование CSS для скрытия вашего элемента "carrier"). Это совершенно справедливо.

в качестве общего направления, я бы попробовал использовать атрибуты данных HTML5. Там нет ничего, чтобы остановить вас положить в действительном JSON. например:

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

Если вы используете jQuery, то вернуть его так же просто, как:

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

этот метод встраивания 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>

просто нет способа избежать/кодирования.

Я бы предложил поместить JSON во встроенный скрипт с обратным вызовом функции (вроде JSONP):

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

Если выполняемый скрипт загружен после документа, вы можете сохранить его где-нибудь, возможно, с дополнительным аргументом идентификатора: someCallback("stuff", { ... });

моя рекомендация состояла бы в том, чтобы хранить данные JSON во внешнем .json файлы, а затем получить эти файлы через Ajax. Вы не помещаете код CSS и JavaScript на веб-страницу (inline), так почему бы вам сделать это с помощью JSON?

посмотреть правило № 3.1 в шпаргалке профилактики XSS OWASP.

скажем, вы хотите включить этот JSON в HTML:

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

создать скрытый <div> в HTML. Затем экранируйте свой 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 элемента с помощью JavaScript и разбора его:

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