JavaScript raises SyntaxError with data rendered in Jinja template

后端 未结 3 1197
无人共我
无人共我 2020-11-21 13:57

I am trying to pass data as JSON from a Flask route to a Jinja template rendering JavaScript. I want to iterate over the data using JavaScript. The browser shows Syn

相关标签:
3条回答
  • 2020-11-21 14:05

    I could archive it using the following code sample.

    <script>
        console.log(JSON.parse({{json|safe}}))
    </script>
    
    0 讨论(0)
  • 2020-11-21 14:14

    Flask's Jinja environment automatically escapes data rendered in HTML templates. This is to avoid security issues if the dev tries to render untrusted user input.

    Since you are passing a Python object to be treated as JSON, Flask provides the tojson filter which automatically dumps the data to JSON and marks it safe.

    return render_template('tree.html', tree=tree)
    
    var tree = {{ tree|tojson }};
    

    When you just look at the data rendered in HTML, it looks correct because the browser displays the escaped symbols as the real symbols (although in this case you're seeing the string representation of a Python dict, not JSON, so there's still some issues like u markers).

    Previous versions of Flask didn't mark the dumped data safe, so you might come across examples like {{ tree|tojson|safe }}, which isn't required anymore.


    If you're not rendering JSON (or you already dumped the JSON to a string), you can tell Jinja that data is safe to render without escaping by using the safe filter.

    # already dumped to json, so tojson would double-encode it
    return render_template('tree.html', tree=json.dumps(tree))
    
    var tree = {{ tree|safe }};
    

    You can also wrap the string in Markup before rendering it, it's equivalent to the safe filter.

    # already dumped and marked safe
    return render_template('tree.html', tree=Markup(json.dumps(tree)))
    
    var tree = {{ tree }};
    

    If you're not passing this data to JavaScript, but using it in Jinja instead, you don't need JSON. Pass the actual Python data, don't call tojson on it, and use it as you would any other data in the template.

    return render_template('tree.html', tree=tree)
    
    {% for item in tree %}
        <li>{{ item }}</li>
    {% endfor %}
    
    0 讨论(0)
  • 2020-11-21 14:14

    The problem is that your server returns not JSON, but rendered HTML, which escapes some of the symbols with & notation.

    Instead of using

    return render_template("folder.html", data=tree)
    

    try

    return flask.jsonify(**tree)
    
    0 讨论(0)
提交回复
热议问题