Best way to store JSON in an HTML attribute?

I need to put a JSON object in an attribute of an HTML element.

  • HTML should not check.

    The answer to this question is Quentin: Save JSON in the data-* attribute , which is valid HTML5.

  • The JSON object can be of any size - i.e. huge

    Answer by Maiku Mori: The limit for the HTML attribute is potentially 65536 characters .

  • What if json contains special characters? e.g. {foo: '<"bar/>'}

    Answered by Quentin: Encode a JSON string before placing it in an attribute, in accordance with normal conventions. For PHP, use the htmlentities() function .




EDIT - sample solution using PHP and jQuery

Writing JSON to the 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> 

Retrieving JSON with 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); }); 
+85
json javascript html php
Sep 06 '11 at 15:52
source share
7 answers

HTML should not check.

Why not? Validation is a really easy QA that catches a lot of bugs. Use the HTML 5 data-* attribute.

A JSON object can be of any size (i.e. huge).

I have not seen any documentation on browser restrictions for attribute sizes.

If you run them, save the data in <script> . Define the element and id map element for the property names in this object.

What if json contains special characters? (e.g. {test: '<"myString /">'})

Just follow the normal rules to include untrusted data in attribute values. Use &amp; and &quot; (if you wrap the attribute value in double quotes) or &#x27; (if you wrap the attribute value in single quotes).

Please note, however, that this is not JSON (for which property names should be strings and strings separated with double quotes only).

+32
Sep 06 2018-11-15T00:
source share

Depending on where you put it,

  • In the <div> , as you requested, you need to make sure that JSON does not contain special HTML files that can run a tag, HTML comment, inline doctype, etc. You need to avoid at least < and & so that the original character does not appear in the escape sequence.
  • In the <script> elements you need to make sure that the JSON does not contain the end tag </script> or the escaping of the text border: <!-- or --> .
  • In event handlers, you need to make sure that JSON retains its value, even if it has objects that resemble HTML objects and do not violate attribute boundaries ( " or ' ).

For the first two cases (and for old JSON parsers) you should encode U + 2028 and U + 2029, since they are newline characters in JavaScript, even if they are allowed in non-JSON encoded strings.

For correctness, you need to avoid the \ and JSON characters, and it will never be a bad idea to always encode NUL.

If HTML can be served without encoding the content, you must encode + to prevent UTF-7 attacks .

In any case, the following table of screens will work:

  • NUL → \u0000
  • CR → \n or \u000a
  • LF → \r or \u000d
  • "\u0022
  • &\u0026
  • '\u0027
  • +\u002b
  • /\/ or \u002f
  • <\u003c
  • >\u003e
  • \\\ or \u005c
  • U + 2028\u2028
  • U + 2029 → \u2029

So, the JSON string value for the text Hello, <World>! with a new line at the end will be "Hello, \u003cWorld\u003e!\r\n" .

+15
Sep 06 2018-11-11T00:
source share

Another way you can do this is to put json data inside the <script> , but not with type="text/javascript" , but with type="text/bootstrap" or type="text/json" , to avoid javascript execution.

Then, at some point 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; } } 

On the server side, you can do something like this (this example with php and twig ):

 <script id="my_model" type="text/json"> {{ my_model|json_encode()|raw }} </script> 
+8
Feb 13 '14 at 7:31
source share

You can use 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()); 

Exit

First Name: Jayson Last Name: Monterroso

Check it out: http://learn.knockoutjs.com/

+5
Jul 24 2018-12-12T00:
source share

Another option is base64 to encode a JSON string, and if you need to use it in your javascript, then decode it with the atob() function.

 var data = JSON.parse(atob(base64EncodedJSON)); 
+4
Apr 28 '16 at 15:00
source share

Nothing special here. From PHP, give the JSON string a run through htmlspecialchars to make sure that no special characters can be interpreted as HTML. No exit is required from Javascript; just set the attribute and you're good to go.

+2
Sep 06 2018-11-15T00:
source share

What you can do is use cdata strong> around your / s element, like this

 <![CDATA[ <div class='log' mydata='${aL.logData}'>${aL.logMessage}</div> ]]> 

where mydata is the raw json string. Hope this helps you and others.

+1
Sep 07
source share



All Articles