I'm thinking about embedding arbitrary JSON in the DOM like this:
<script type="application/json" id="stuff">
{
"unicorns": "awesome",
"abc": [1, 2, 3]
}
</script>
This is similar to the way one might store an arbitrary HTML template in the DOM for later use with a JavaScript template engine. In this case, we could later retrieve the JSON and parse it with:
var stuff = JSON.parse(document.getElementById('stuff').innerHTML);
This works, but is it the best way? Does this violate any best practice or standard?
Note: I'm not looking for alternatives to storing JSON in the DOM, I've already decided that's the best solution for the particular problem I'm having. I'm just looking for the best way to do it.
My recommendation would be to keep JSON data in external
.json
files, and then retrieve those files via Ajax. You don't put CSS and JavaScript code onto the web-page (inline), so why would you do it with JSON?As a general direction, I would try using HTML5 data attributes instead. There's nothing to stop you putting in valid JSON. e.g.:
If you're using jQuery, then retrieving it is as easy as:
I think your original method is the best. The HTML5 spec even addresses this use:
Read here: http://dev.w3.org/html5/spec/Overview.html#the-script-element
You've done exactly that. What is not to love? No character encoding as needed with attribute data. You can format it if you want. It's expressive and the intended use is clear. It doesn't feel like a hack (e.g. as using CSS to hide your "carrier" element does). It's perfectly valid.
This method of embedding json in a script tag has a potential security issue. Assuming the json data originated from user input, it is possible to craft a data member that will in effect break out of the script tag and allow direct injection into the dom. See here:
http://jsfiddle.net/YmhZv/1/
Here is the injection
There is just no way around escaping/encoding.
See Rule #3.1 in OWASP's XSS prevention cheat sheet.
Say you want to include this JSON in HTML:
Create a hidden
<div>
in HTML. Next, escape your JSON by encoding unsafe entities (e.g., &, <, >, ", ', and, /) and put it inside the element.Now you can access it by reading the
textContent
of the element using JavaScript and parsing it:I'd suggest to put JSON into an inline script with a function callback (kind of JSONP):
If the executing script is loaded after the document you can store this somewhere, possibly with an additional identifier argument:
someCallback("stuff", { ... });