Мне нужно поместить объект JSON в атрибут элемента HTML.
HTML не нужно проверять.
Ответ: Quentin: Храните JSON в атрибуте data-*
, который действителен для HTML5.
Объект JSON может быть любого размера – то есть огромного
Ответа на вопрос Maiku Mori: Предел для HTML-атрибута может составлять 65536 символов .
Что делать, если JSON содержит специальные символы? например {foo: '<"bar/>'}
Ответ: Quentin: Кодируйте строку JSON перед тем, как поместить ее в атрибут, в соответствии с обычными соглашениями. Для PHP используйте htmlentities()
.
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); });
HTML не нужно проверять.
Почему нет? Проверка действительно легкая QA, которая ловит много ошибок. Используйте атрибут data-*
HTML 5.
Объект JSON может быть любого размера (т.е. огромного).
Я не видел никакой документации по ограничениям браузера для размеров атрибутов.
Если вы запустили их, сохраните данные в <script>
. Определите id
объекта и объекта карты s в именах свойств этого объекта.
Что делать, если JSON содержит специальные символы? (например, {test: '<"myString />'})
Просто следуйте обычным правилам для включения ненадежных данных в значения атрибутов. Использовать &
и "
(если вы '
значение атрибута в двойные кавычки) или '
(если вы переносите значение атрибута в одинарные кавычки).
Обратите внимание, однако, что это не JSON (который требует, чтобы имена свойств были строками, а строки были разделены только с двойными кавычками).
В зависимости от того, где вы выразились,
<div>
как вы просили, вам нужно убедиться, что JSON не содержит специальных HTML-файлов, которые могут запускать тег, комментарий HTML, встроенный doctype и т. Д. Вам нужно избегать, по крайней мере, <
и так, чтобы исходный символ не появляется в экранированной последовательности. <script>
вам необходимо убедиться, что JSON не содержит конечный тег </script>
или экранирование границы текста: <!--
или -->
. "
или '
). Для первых двух случаев (и для старых парсеров JSON) вы должны кодировать U + 2028 и U + 2029, поскольку они являются символами новой строки в JavaScript, даже если они разрешены в строках, не кодированных в JSON.
Для правильности вам нужно сбежать с символами кавычек \
и JSON, и никогда не будет плохой идеей всегда кодировать NUL.
Если HTML может быть подан без кодировки содержимого, вы должны кодировать +
чтобы предотвратить атаки UTF-7 .
В любом случае будет работать следующая таблица экранирования:
\u0000
\n
или \u000a
\r
или \u000d
"
-> \u0022
&
-> \u0026
'
-> \u0027
+
-> \u002b
/
-> \/
или \u002f
<
-> \u003c
>
-> \u003e
\
-> \\
или \u005c
\u2028
\u2029
Итак, строковое значение JSON для текста Hello, <World>!
с новой "Hello, \u003cWorld\u003e!\r\n"
в конце будет "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 и twig ):
<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>
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/
Другой вариант – base64 закодировать строку JSON, и если вам нужно использовать ее в своем javascript, декодируйте ее с помощью функции atob()
.
var data = JSON.parse(atob(base64EncodedJSON));
Ничего особенного здесь. Из PHP дайте строке JSON выполнить htmlspecialchars
чтобы убедиться, что никакие специальные символы не могут быть интерпретированы как HTML. Из Javascript не требуется никакого выхода; просто установите атрибут, и вам хорошо идти.
Что вы можете сделать, так это использовать cdata вокруг вашего элемента / s
<![CDATA[ <div class='log' mydata='${aL.logData}'>${aL.logMessage}</div> ]]>
где mydata является сырой json-строкой. Надеюсь, это поможет вам и другим.