Лучший способ сохранить JSON в атрибуте HTML?


мне нужно отправить JSON-объект в качестве атрибута в HTML-элемент.

  1. HTML не нужно проверять.

    ответил Квентин: храните JSON в data-* атрибут, что является допустимым HTML5.

  2. объект JSON может быть любого размера-т. е. огромный

    ответил майку Мори:предел для an HTML атрибут потенциально 65536 символов.

  3. что делать, если JSON содержит специальные символы? например,{foo: '<"bar/>'}

    ответил Квентин: закодировать в JSON-строку, прежде чем положить его в атрибут, так как в соответствии с обычными соглашениями. для PHP, используйтеhtmlentities()

7 92

7 ответов:

HTML не нужно проверять.

почему бы и нет? Проверка действительно легко QA, который ловит много ошибок. Используйте HTML 5 .

объект JSON может быть любого размера (т. е. огромный).

Я не видел никакой документации по ограничениям браузера на размеры атрибутов.

если вы столкнетесь с ними, то хранить данные в <script>. Определите объект и элемент карты ids к именам свойств в этот объект.

что делать, если JSON содержит специальные символы? (например, {test: ''})

просто следуйте обычным правилам для включения ненадежных данных в значения атрибутов. Используйте &amp; и &quot; (если вы заключаете значение атрибута в двойные кавычки) или &#x27; (если вы заключаете значение атрибута в одинарные кавычки).

обратите внимание, однако, что это не JSON (который требует, чтобы имена свойств были строками и строки были разделяется только двойными кавычками).

в зависимости от того, куда вы его положили,

  • на <div> Как вы просили, вам нужно убедиться, что JSON не содержит специальных HTML, которые могут запускать тег, HTML-комментарий, встроенный doctype и т. д. Вам нужно бежать по крайней мере < и & таким образом, чтобы исходный символ не появлялся в экранированной последовательности.
  • In <script> элементы вам нужно убедиться, что JSON не содержит конечный тег </script> или экранирование границы текста: <!-- или -->.
  • в обработчиках событий вам нужно убедиться, что JSON сохраняет свое значение, даже если у него есть вещи, которые выглядят как HTML-объекты и не нарушают границы атрибутов (" или ').

для первых двух случаев (и для старых парсеров JSON) вы должны кодировать U+2028 и U+2029, поскольку это символы новой строки в JavaScript, даже если они разрешены в строках, не закодированных в JSON.

для корректности, нужно побег \ и символы цитаты 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

Итак, строковое значение JSON для текста Hello, <World>! С новой строкой в конце будет "Hello, \u003cWorld\u003e!\r\n".

другой способ, которым вы можете это сделать-это поместить данные json внутрь <script> тег, но не с type="text/javascript", но с type="text/bootstrap" или type="text/json" введите, чтобы избежать выполнения javascript.

потом, в каком-то месте вашей программы, вы можете задать его таким образом:

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 и веточка):

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

Вы можете использовать knockoutjs,

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

нокаут.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());

выход

имя: Джейсон Фамилия: Monterroso

проверить это: http://learn.knockoutjs.com/

другой вариант-base64 кодировать строку JSON, и если вам нужно использовать ее в своем javascript, декодируйте ее с помощью

ничего особенного здесь. Из PHP, дайте строку JSON запустить через htmlspecialchars чтобы убедиться, что никакие специальные символы не могут быть интерпретированы как HTML. Из Javascript не нужно бежать; просто установите атрибут, и вы хорошо пойдете.

что вы можете сделать, это использовать cdata вокруг вашего элемента / s, как это

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

где mydata-это необработанная строка json. Надеюсь, это поможет вам и другим.