JavaScript вызывает синтаксическую ошибку с данными, отображаемыми в шаблоне Jinja

#jquery #flask

Вопрос:

Я пытаюсь передать данные в формате JSON из маршрута Flask в шаблон Jinja, отображающий JavaScript. Я хочу перебрать данные с помощью JavaScript. Браузер показывает SyntaxError: Unexpected token 'amp;'. Expected a property name. , когда JSON.parse вызывается для отображаемых данных. Как использовать визуализированные данные JSON в JavaScript?

 var obj = JSON.parse({{ data }}) for (i in obj){  document.write(obj[i].text   "lt;br /gt;"); }  
 def get_nodes(node):  d = {}  if node == "Root":  d["text"] = node  else:  d["text"] = node.name   getchildren = get_children(node)  if getchildren:  d["nodes"] = [get_nodes(child) for child in getchildren]  return d  tree = get_nodes("Root") return render_template("folder.html", data=tree)  

Если я просто вставлю {{ data }} HTML-часть, то то, что я вижу, выглядит правильно.

 {'text': 'Root', 'nodes': [{'text': u'Prosjekt3'}, {'text': u'Prosjekt4', 'nodes': [{'text': u'mappe8'}]}]}  

Ответ №1:

Среда Jinja Flask автоматически экранирует данные, отображаемые в HTML-шаблонах. Это делается для того, чтобы избежать проблем с безопасностью, если разработчик попытается предоставить ненадежный пользовательский ввод.

Поскольку вы передаете объект Python для обработки как JSON, Flask предоставляет tojson фильтр, который автоматически сбрасывает данные в JSON и помечает их как безопасные.

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

Когда вы просто смотрите на данные, отображаемые в HTML, это выглядит правильно, потому что браузер отображает экранированные символы как настоящие символы (хотя в этом случае вы видите строковое представление Python dict, а не JSON, поэтому все еще есть некоторые проблемы, такие как u маркеры).

Предыдущие версии Flask не отмечали сохранность сброшенных данных, поэтому вы можете столкнуться с такими примерами , как {{ tree|tojson|safe }} , что больше не требуется.


Если вы не визуализируете JSON (или вы уже сбросили JSON в строку), вы можете сообщить Jinja, что данные безопасно визуализировать без экранирования с помощью safe фильтра.

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

Вы также можете обернуть строку Markup перед ее отображением, это эквивалентно safe фильтру.

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

Если вы не передаете эти данные в JavaScript, а вместо этого используете их в Jinja, вам не нужен JSON. Передайте фактические данные Python, не вызывайте tojson их и используйте их, как любые другие данные в шаблоне.

 return render_template('tree.html', tree=tree)  
 {% for item in tree %}  lt;ligt;{{ item }}lt;/ligt; {% endfor %}  

Ответ №2:

Я мог бы заархивировать его, используя следующий пример кода.

 lt;scriptgt;  console.log(JSON.parse({{json|safe}})) lt;/scriptgt;  

Ответ №3:

Проблема в том, что ваш сервер возвращает не JSON, а визуализированный HTML, который экранирует некоторые символы с помощью обозначенияamp;.

Вместо использования

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

пробовать

 return flask.jsonify(**tree)