3

I am sitting on a Flask based webapplication. In theory I want to load a JSON file from disk and give it to javascript on the website.

def getData():
    check_for_update()
    with open(LOCAL_file,"rb") as myfile:
        data = json.load(myfile)
    udate = data["today"] 
    return (udate, data)

then I send it to the page with

return render_template('./index2.html', udate = thisdata[0], data = json.dumps(thisdata[1]))

Now on the page I simply try

<script>
var myjson = JSON.parse({{data}})
</script>

which then results in something like this

enter image description here

This can't not be parsed.When I copy and paste it it works fine, and python does not complain either.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Jörg Stephan
  • 33
  • 1
  • 5
  • You have two different problems here and are running into them sequentially, which makes it hard to close this as a duplicate. They are: 1. [Mustache JS Templating - How do I embed a variable in a script tag string?](http://stackoverflow.com/questions/9051281/mustache-js-templating-how-do-i-embed-a-variable-in-a-script-tag-string) 2. [I keep getting “Uncaught SyntaxError: Unexpected token o”](http://stackoverflow.com/questions/8081701/i-keep-getting-uncaught-syntaxerror-unexpected-token-o) – Quentin Oct 17 '16 at 08:35
  • @Quentin: this is not a Mustache template. The default Flask template enginge, Jinja2, also uses `{{..}}` placeholders. And the OP simply forgot to disable the standard HTML escaping. – Martijn Pieters Oct 17 '16 at 08:51
  • The output produced in HTML is still *text*. It's preferable if you pasted that as text here rather than use an image, as image contents can't be copied or searched for. – Martijn Pieters Oct 17 '16 at 08:58

1 Answers1

6

data is HTML escaped, because Jinja2 by default escapes everything to be safe to embed in an HTML page.

It's much better to not encode to JSON in the view, do this in the template instead, and use the Flask tojson and safe filters.

So in the view pass in thisdata[1] unencoded:

return render_template(
    './index2.html', udate=thisdata[0], data=thisdata[1])

and in the view:

<script>
var myjson = {{ data|tojson|safe }};
</script>

tojson produces JSON data that is also HTML-safe (albeit with " quotes, so it is not suitable for embedding in a HTML tag attribute), and the safe filter can be used to switch off the HTML-encoding. There is no need to use JSON.parse() here, the resulting JSON produced by tojson is a strict JavaScript subset.

See the JSON Support section in the API documentation:

The htmlsafe_dumps() function of this json module is also available as filter called |tojson in Jinja2. Note that inside script tags no escaping must take place, so make sure to disable escaping with |safe if you intend to use it inside script tags[.]

and the Standard Filters section of the Flask Templates documentation:

tojson()
This function converts the given object into JSON representation. This is for example very helpful if you try to generate JavaScript on the fly.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343