Coder Perfect

What’s the best approach to put JSON in an HTML attribute?

Problem

I need to add a JSON object into an HTML element’s attribute.

EDIT: Here’s an example of a PHP and jQuery approach.

Incorporating JSON into an HTML attribute:

<?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>

Using jQuery to get the JSON:

$('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);

});

Asked by BadHorsie

Solution #1

What’s to stop you? Validation is a simple QA procedure that detects a large number of errors. Use the data-* attribute in HTML 5.

I haven’t seen any documentation on attribute size restrictions in browsers.

If you do come upon one, save the information in a script. Create an object and map element ids to the object’s property names.

Simply follow the standard procedures for incorporating untrusted input into attribute values. If you’re wrapping the attribute value in double quotations, use & and “; if you’re wrapping it in single quotes, use ‘.

It should be noted, however, that this is not JSON (which requires that property names be strings and strings be delimited only with double quotes).

Answered by Quentin

Solution #2

Depending on where you put it, it can be useful.

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.

You must escape and JSON quote characters for accuracy, and it is always a good idea to encode NUL.

You should encode + to prevent UTF-7 attacks if the HTML might be provided without a content encoding.

In any event, the fleeing table below will suffice:

As a result, the JSON string value for the text Hello, World! “Hello, u003cWorldu003e!rn” would be “Hello, u003cWorldu003e!” with a newline at the end.

Answered by Mike Samuel

Solution #3

Another option is to place json data inside a script> tag with type=”text/bootstrap” or type=”text/json” instead of type=”text/javascript” to avoid javascript execution.

Then, somewhere in your program, you can request it as follows:

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;
  } 
}

You can do something like this on the server side (this example uses php and twig):

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

Answered by Sergey Kamardin

Solution #4

Another alternative is to base64 encode the JSON string and then decode it with the atob() function if you need to utilize it in javascript.

var data = JSON.parse(atob(base64EncodedJSON));

Answered by Pavel Petrov

Solution #5

The code below would work for simple JSON items.

Encode:

var jsonObject = { numCells: 5, cellWidth: 1242 };
var attributeString = escape(JSON.stringify(jsonObject));

Decode:

var jsonString = unescape(attributeString);
var jsonObject = JSON.parse(jsonString);

Answered by Crashalot

Post is based on https://stackoverflow.com/questions/7322682/best-way-to-store-json-in-an-html-attribute