108

I have a dynamically generated page where I want to use a static JavaScript and pass it a JSON string as a parameter. I have seen this approach used by Google (see Google's +1 Button: How do they do it?).

But how should I read the JSON string from the JavaScript?

<html>
  <head>
    <script src="jquery-1.6.2.min.js"></script>
    <script src="myscript.js">{"org": 10, "items":["one","two"]}</script>
  </head>
  <body>
    Hello
  </body>
</html>

In this JavaScript I would like to use the JSON argument {"org": 10, "items":["one","two"]} from the HTML document. I don't know if it's best to do it with jQuery or without.

$(function() {
    // read JSON

    alert("the json is:")
})
Jonas
  • 121,568
  • 97
  • 310
  • 388

5 Answers5

219

I would change the script declaration to this:

<script id="data" type="application/json">{"org": 10, "items":["one","two"]}</script>

Note type and id fields. After that

var data = JSON.parse(document.getElementById('data').textContent);

will work just fine in all browsers.

The type="application/json" is needed to prevent browser from parsing it while loading.

And the reason why we use textContent instead of innerHTML or innerText to read the raw Json text is because innerHTML tries to parse the contents as HTML which will lead to slower performance and possible parsing bugs and XSS attacks, and innerText won't grab the raw text and will instead look for human-visible text, whereas textContent grabs the pure text as-is (which is what you want). See https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent for more details about why innerHTML and innerText are bad.

Mitch McMabers
  • 3,634
  • 28
  • 27
c-smile
  • 26,734
  • 7
  • 59
  • 86
  • Well, I want the script-tag point to a JavaScript, so it's not only for JSON. The JSON is only an argument to the script. – Jonas Oct 31 '11 at 16:10
  • 4
    According to HTML5 spec: http://dev.w3.org/html5/markup/script.html the ` – c-smile Oct 31 '11 at 16:24
  • 12
    @WoIIe Because jQuery is used already by TS, check `` there. – c-smile Apr 14 '14 at 20:07
  • I like the jquery usage. I mean, how many more fractions of a millisecond will you shave off by using vanilla javascript (in this case)? – Captain Hypertext Oct 07 '15 at 00:18
  • 3
    Pay attention that this is not safe, it allows XSS, https://codepen.io/anon/pen/xevgEM – felixmosh May 02 '19 at 16:39
  • @felixmosh That's true for any inclusion on the page. Same thing can be done with ` – c-smile May 02 '19 at 18:59
  • This seems to have some caveats. We had json containing SVGs as strings and they caused json parsing errors when using this technique. The workaround was to base64 encode it and decode it using atob() before passing to JSON.parse(). – esamatti Oct 06 '21 at 10:16
  • 1
    Note: You can't load local JSON files using the `src` attribute this way. `textContent` etc. will return an empty string. – Krisztián Balla Sep 19 '22 at 11:01
12

I ended up with this JavaScript code to be independent of jQuery.

var jsonElement = document.getElementById('json-script-tag');
var myObject = JSON.parse(jsonElement.textContent);
Jonas
  • 121,568
  • 97
  • 310
  • 388
  • 47
    Why not just give the script an ID and grab it with `document.getElementById`? That way, you don't have to remember to keep it last. Nor will whoever else changes the page in the future. – George Oct 06 '12 at 20:50
  • The original version of this answer was inspired by the link in the question, https://stackoverflow.com/questions/6713197/googles-1-button-how-do-they-do-it – Jonas Nov 23 '20 at 12:45
  • Should one really depend on jQuery just to do this? – ozanmuyes Jun 15 '23 at 01:25
  • 1
    @ozanmuyes No, and that’s why I wrote code independent of jQuery. – Jonas Jun 15 '23 at 09:44
5

To read JSON in <script id="myJSON"> use

var manifest= document.getElementById('myJSON').innerHTML; //sets manifest to the text in #myJSON
manifest= JSON.parse(manifest) //Converts text into JSON

You can also use methods to point to the script like document.scripts[0]

    //var manifest= JSON.parse(document.getElementById('myJSON').innerHTML); /*Shortend of 2&3*/
var manifest= document.getElementById('myJSON').innerHTML; //Gets text in #myJSON
manifest= JSON.parse(manifest) //Converts it into JSON
document.getElementById('test').innerHTML= manifest.name+ '<br/>'+ manifest.otherOptions; //Displays it
console.log('manifest')
console.log(manifest);
<head>
<script type="application/json" id="myJSON">
  {"name":"Web Starter Kit", "otherOptions":"directly here"}
</script>
</head>
<body>
<p id="test"></p>
</body>
Zekrom_Vale
  • 344
  • 4
  • 10
3
JSON.parse($('script[src="mysript.js"]').html());

or invent some other method to identify the script.

Maybe instead of .html() you might need .text(). Not sure. Try them both.

Emil Ivanov
  • 37,300
  • 12
  • 75
  • 90
0

Like that will be working?

<script id="data" type="application/json" src="https://mycstripc.co">
var data = JSON.parse(document.getElementById('data').textContent);
</script>
Makyen
  • 31,849
  • 12
  • 86
  • 121
Kamil Dąbrowski
  • 984
  • 11
  • 17