Is there a standard for embedding JSON in HTML?

32,296

Solution 1

Reasons for using inline JSON (instead of a JSON-P service)

You can inline JSON-P as well. OK, you just call that method "inline script", but it has the advantages of both :-)

Solution 2

What you suggest is absolutely correct. The type attributes of the script tag must be a valid MIME descriptor. According to the official JSON RFC section 6 "IANA Considerations":

The MIME media type for JSON text is application/json.
Type name: application
Subtype name: json

So your HTML is valid:

<script id="data" type="application/json">
    {
        "foo" : "bar"
    }
</script> 

And, no, there are no additional risks involved in doing this.

Solution 3

I am answering my own question since I have had to find a solution. My solution is based on what Bergi suggested using inline JSONP. It is a better solution than finding an answer to my actual question since no manual JSON-parsing is required.

The JSON-data (and HTML) is generated with Java Server Pages (JSP).

Step 1

A custom variable name is created using JSP. It will be used as the javascript global variable to which the json data will be assigned to. The name is randomly generated to prevent naming conflicts on the same page.

<c:set var="jsonpVarName">jsnpData<%= java.lang.Math.round(java.lang.Math.random() * 1000000) %></c:set>    

Step 2 The script tag has a cssClassname to identify it by and a data-var-attribute, so that the custom variable name can be determined. ${ctrl.json}is JSP and prints out JSON. Unlike JSONP which uses a callback-Function, a global variable is used. So far I have not experienced any drawbacks.

<script class="data" data-var="${jsonpVarName}" type="text/javascript">
    window.${jsonpVarName} = ${ctrl.json};
</script>

Step 3 Accessing the data (using jQuery) is as easy as:

var data = window[$('script.data').data('var')];

Example with context

HTML

<div class="myWidget">
    <button class="fetchData">Fetch Data</button>


    <c:set var="jsonpVarName">jsnpData<%= java.lang.Math.round(java.lang.Math.random() * 1000000) %></c:set>

    <script class="data" data-var="${jsonpVarName}" type="text/javascript">
        window.${jsonpVarName} = ${ctrl.json};
    </script>

</div> 

Javascript

$('button.fetchData', '.myWidget').click(function (e) {

    var data = window[$('script.data', '.myWidget').data('var')];    

});

I'm using inline JSONP to load JSON-data which is required on page load. It isn't a lot of data and it's one HTTP-Request less.

Share:
32,296

Related videos on Youtube

T. Junghans
Author by

T. Junghans

“Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” –Antoine de Saint-Exupery

Updated on October 17, 2020

Comments

  • T. Junghans
    T. Junghans over 3 years

    I would like to embed JSON in HTML. The most elegant solution I have found makes use of the script-tag and the mime media type application/json.

    <script id="data" type="application/json">
        {
            "foo" : "bar"
        }
    </script> 
    

    Is this the standard way of embedding JSON? If not, are there any risks with the above solution?

    Reasons for using inline JSON (instead of a JSON-P service):

    • Small amounts of JSON-data
    • Less HTTP-requests
    • Preference for inline-JSON to data in HTML-attributes

    [UPDATE] Reason for embedding json.

    I have a gallery widget for a website with very high traffic. The gallery can consist of a 100 images or more. I am only showing one image at a time and the rest of the images will be lazy loaded. However the information (image src) to all images will be rendered in the html on page load. There are various ways to render the image information in the html. Instead of using JSON I could also use html data attributes as shown below:

    <li class="image" data-src="image-path.jpg">
        <!-- image tag will be created here using javascript -->
    </li>
    

    Will result in:

    <li class="image image-loaded" data-src="image-path.jpg">
        <img src="image-path.jpg" />
    </li>
    

    The disadvantage with the above solution is the extra markup. I would rather use JSON and a Javascript-Templating engine such as doT.js.

    • PeeHaa
      PeeHaa over 11 years
      What are you going to do with the json your are "embedding"?
    • dead
      dead over 11 years
      You're better off storing the json as an object in javascript. There is no reason to have embedded json, unless you're somehow going to avoid using javascript to access that json again.
    • JJJ
      JJJ over 11 years
      JSON is a method for transferring data. It's not something that should be used for its own sake. Especially when you're dealing with JavaScript, there's practically no reason to prefer JSON (JavaScript Object Notation) over actual JavaScript objects.
    • intuitivepixel
      intuitivepixel over 11 years
      Is it static content you want to embed? Or would you serve the HTML files prepopulated with the embedded JSON? Otherwise I don't see any advantage to embed the JSON directly in HTML
    • T. Junghans
      T. Junghans over 11 years
      @PeeHaa: I have updated my question with a reason.
    • T. Junghans
      T. Junghans over 11 years
      @Horo: Yes, there is a reason. I don't like mixing data and logic (model and controller). I also don't like mixing data and html (model and view), but this is the situation now.
    • T. Junghans
      T. Junghans over 11 years
      @Juhana: JSON is not a method. It is a lightweight data-interchange format.
    • T. Junghans
      T. Junghans over 11 years
      @mokane: Yes, it's static content and I agree with you.
    • JJJ
      JJJ over 11 years
      @TJ. I didn't mean "method" as a programming term, only as a synonym for "means".
    • T. Junghans
      T. Junghans over 11 years
      @Juhana: Ok, I see. But I mention in my question that JSON-P is not an option. Of course JSON is awesome for transferring data.
    • Bergi
      Bergi over 11 years
      @TJ.: Why is JSONP not an option? Just make it inline-JSON-P :-)
    • T. Junghans
      T. Junghans over 11 years
      @Bergi: See my comment to your answer below, you are right and I was on Mars.
    • caglaror
      caglaror over 8 years
      On my department every user have to use chrome. And i am embedding json strings directly into elements values. Some how double quotes doesn't make trouble. I mean no errors. Also i transfer-update these embedded values (json type) to server with AJAX.
  • T. Junghans
    T. Junghans over 11 years
    This doesn't answer my question
  • T. Junghans
    T. Junghans over 11 years
    You're absolutely right, but I don't need JSON-P when using JSON inline.
  • Bergi
    Bergi over 11 years
    With JavaScript object literals, you a) don't need JSON.parse etc. b) can use Date objects and similar non-JSON things c) can directly append the gallery code (instead of separate <script> elements) d) don't need to wait for DOMready to extract the JSON
  • T. Junghans
    T. Junghans over 11 years
    a) and b) make sense, although I'm just receiving plain text data, so b) doesn't worry me. Could you explain c) I'm not sure I understand correctly? d) is no issue, since Javascript execution begins only when the DOM is loaded.
  • T. Junghans
    T. Junghans over 11 years
    I was sleeping when I added my first comment to your answer. Not having to use JSON.parse is a plus and I can do that if I assign the JSON to a global variable, similar to JSON-P.
  • T. Junghans
    T. Junghans over 11 years
    And using JSON-P makes my main question almost irrelevant :-)
  • Chad Brown
    Chad Brown over 11 years
    I believe that mahmoud is saying use a templating engine like json2html to dynamically convert your JSON feed into html WHEN you need it. So do something like this .. embed the JSON inside a nice script tag during your server page load then use json2html to convert images (when needed) into actual 'img' elements.
  • T. Junghans
    T. Junghans over 11 years
    Giving you the credit. I have also added an answer with an example further below.
  • Tom McKenzie
    Tom McKenzie over 9 years
    Please read benalpert.com/2012/08/03/preventing-xss-json.html for a possible XSS vector.
  • Domi
    Domi about 4 years
    @TomMcKenzie Right, that is a risk that pertains to any user-generated content. I assumed that OP generates a json file that is safe for consumption to begin with.
  • vincent thorpe
    vincent thorpe over 2 years
    and how can I fetch this?
  • Domi
    Domi over 2 years
    @vincentthorpe you don't fetch it (fetch in this context means that you download data that you don't already have). Instead, you can just access it via DOM selector. E.g. in the example above: document.querySelector('#data') (because the script tag has id="data" ).