Лучший способ хранения JSON в атрибуте HTML?
Мне нужно поместить объект JSON в атрибут элемента HTML.
EDIT - пример решения с использованием PHP и jQuery
Запись JSON в атрибут HTML:
<?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>
Извлечение JSON с помощью jQuery:
$('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);
});
Ответы
Ответ 1
HTML не должен проверять.
Почему бы и нет? Проверка действительно легкая QA, которая ловит много ошибок. Используйте атрибут HTML 5 data-*
.
Объект JSON может быть любого размера (т.е. огромного).
Я не видел никакой документации по ограничениям браузера для размеров атрибутов.
Если вы запустили их, сохраните данные в <script>
. Определите элемент и элемент карты id
для имен свойств в этом объекте.
Что делать, если JSON содержит специальные символы? (например, {test: '< "myString/" > '})
Просто следуйте нормальным правилам для включения ненадежных данных в значения атрибутов. Используйте &
и "
(если вы обертываете значение атрибута в двойных кавычках) или '
(если вы переносите значение атрибута в одинарные кавычки).
Обратите внимание, однако, что это не JSON (для которого имена свойств должны быть строками и строками разделены только с двойными кавычками).
Ответ 2
В зависимости от того, где вы его положили,
- В
<div>
, как вы просили, вам нужно убедиться, что JSON не содержит специальных HTML файлов, которые могут запускать тег, комментарий HTML, встроенный doctype и т.д. Вам нужно избежать не менее <
и &
таким образом, чтобы исходный символ не появлялся в escape-последовательности.
- В элементах
<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"
.
Ответ 3
Другой способ, которым вы можете это сделать, - поместить данные 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 и twig):
<script id="my_model" type="text/json">
{{ my_model|json_encode()|raw }}
</script>
Ответ 4
Вы можете использовать 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/
Ответ 5
Другим вариантом является base64 кодировать строку JSON, и если вам нужно использовать ее в вашем javascript, то декодируйте ее с помощью функции atob()
.
var data = JSON.parse(atob(base64EncodedJSON));
Ответ 6
Ничего особенного здесь. Из PHP дайте строке JSON пробег через htmlspecialchars
, чтобы убедиться, что никакие специальные символы не могут быть интерпретированы как HTML. Из Javascript не требуется никакого выхода; просто установите атрибут, и вам хорошо идти.
Ответ 7
Что вы можете сделать, это использовать cdatastrong > вокруг вашего элемента /s, как этот
<![CDATA[ <div class='log' mydata='${aL.logData}'>${aL.logMessage}</div> ]]>
где mydata - это сырая строка json. Надеюсь, это поможет вам и другим.