I need to put a JSON object into an attribute on an HTML element.
The HTML does not have to validate.
Answered by Quenti
Depending on where you put it,
<div>
as you asked, you need to ensure that the JSON does not contain HTML specials that could start a tag, HTML comment, embedded doctype, etc. You need to escape at least <
, and &
in such a way that the original character does not appear in the escaped sequence.<script>
elements you need to ensure that the JSON does not contain an end tag </script>
or escaping text boundary: <!--
or -->
."
or '
).For the first two cases (and for old JSON parsers) you should encode U+2028 and U+2029 since those are newline characters in JavaScript even though they are allowed in strings unencoded in JSON.
For correctness, you need to escape \
and JSON quote characters and it's never a bad idea to always encode NUL.
If the HTML might be served without a content encoding, you should encode +
to prevent UTF-7 attacks.
In any case, the following escaping table will work:
\u0000
\n
or \u000a
\r
or \u000d
"
-> \u0022
&
-> \u0026
'
-> \u0027
+
-> \u002b
/
-> \/
or \u002f
<
-> \u003c
>
-> \u003e
\
-> \\
or \u005c
\u2028
\u2029
So the JSON string value for the text Hello, <World>!
with a newline at the end would be "Hello, \u003cWorld\u003e!\r\n"
.
Another option is to base64 encode the JSON string and if you need to use it in your javascript decode it with the atob()
function.
var data = JSON.parse(atob(base64EncodedJSON));
Another thought that could be used is store the JSON data as a base64 string in the attribute and then using window.atob
or window.btoa
to restore it to usable JSON data.
<?php
$json = array("data"=>"Some json data thing");
echo "<div data-json=\"".base64_encode(json_encode($json))."\"></div>";
?>