Подтвердить что ты не робот

Как я могу передавать данные из Flask в JavaScript в шаблоне?

Мое приложение вызывает вызов API, который возвращает словарь. Я хочу передать информацию из этого dict в JavaScript в представлении. Я использую API Карт Google в JS, в частности, поэтому я хотел бы передать ему список кортежей с длинной /lat информацией. Я знаю, что render_template передаст эти переменные виду, чтобы их можно было использовать в HTML, но как я могу передать их JavaScript в шаблоне?

from flask import Flask
from flask import render_template

app = Flask(__name__)

import foo_api

api = foo_api.API('API KEY')

@app.route('/')
def get_data():
    events = api.call(get_event, arg0, arg1)
    geocode = event['latitude'], event['longitude']
    return render_template('get_data.html', geocode=geocode)
4b9b3361

Ответ 1

Вы можете использовать {{ variable }} в любом месте вашего шаблона, а не только в части HTML. Поэтому это должно работать:

<html>
<head>
<script>
var someJavaScriptVar = '{{ geocode[1] }}';
</script>
<body>
<p>Hello World</p>
<button onclick="alert('Geocode: {{ geocode[0] }} ' + someJavaScriptVar)" />
</body>
</html>

Подумайте об этом как о двухэтапном процессе: во-первых, Jinja (использует флеш-память шаблона) генерирует ваш текстовый вывод. Это отправляется пользователю, который выполняет JavaScript, который он видит. Если вы хотите, чтобы ваша переменная Flask была доступна в JavaScript в виде массива, вам нужно создать определение массива в вашем выводе:

<html>
<head>
<script>
var myGeocode = ['{{ geocode[0] }}', '{{ geocode[1] }}'];
</script>
<body>
<p>Hello World</p>
<button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
</body>
</html>

Jinja также предлагает более продвинутые конструкции из Python, поэтому вы можете сократить его до:

<html>
<head>
<script>
var myGeocode = [{{ ', '.join(geocode) }}];
</script>
<body>
<p>Hello World</p>
<button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
</body>
</html>

Вы также можете использовать инструкции for loop, if и многие другие, см. документацию Jinja2 для получения дополнительной информации.

Также посмотрите на ответ ford, который указывает на tojson фильтр, который является дополнением к Стандартный набор фильтров Jinja2.

Ответ 2

Идеальный способ получить почти любой объект Python в объект JavaScript - использовать JSON. JSON отлично подходит для передачи данных между системами, но иногда мы забываем, что это означает JavaScript Object Notation. Это означает, что инъекция JSON в шаблон совпадает с введением кода JavaScript, который описывает объект.

Flask предоставляет фильтр Jinja для этого: tojson сбрасывает структуру в строку JSON и делает ее безопасной, чтобы Jinja не выполнял автозапуск он.

<html>
  <head>
    <script>
      var myGeocode = {{ geocode|tojson }};
    </script>
  </head>
  <body>
    <p>Hello World</p>
    <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
  </body>
</html>

Это работает для любой структуры Python, которая является сериализуемой JSON:

python_data = {
    'some_list': [4, 5, 6],
    'nested_dict': {'foo': 7, 'bar': 'a string'}
}
var data = {{ python_data|tojson }};
alert('Data: ' + data.some_list[1] + ' ' + data.nested_dict.foo + 
      ' ' + data.nested_dict.bar);

Ответ 3

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

Укажите атрибут данных, например:

<div id="mydiv" data-geocode="{{ geocode|tojson }}">...</div>

Затем получите доступ к нему в статическом файле JavaScript так:

// Raw JavaScript
var geocode = JSON.parse(document.getElementById("mydiv").dataset.geocode);

// jQuery
var geocode = JSON.parse($("#mydiv").data("geocode"));

Ответ 4

Еще одно альтернативное решение для тех, кто хочет передать переменные в script, который получен с использованием флэка, мне удалось получить эту работу, указав переменные за пределами, а затем вызвав script следующим образом:

    <script>
    var myfileuri = "/static/my_csv.csv"
    var mytableid = 'mytable';
    </script>
    <script type="text/javascript" src="/static/test123.js"></script>

Если я ввожу переменные jinja в test123.js, это не сработает, и вы получите сообщение об ошибке.

Ответ 5

В качестве альтернативы вы можете добавить конечную точку для возврата своей переменной:

@app.route("/api/geocode")
def geo_code():
    return jsonify(geocode)

Затем выполните XHR для его получения:

fetch('/api/geocode')
  .then((res)=>{ console.log(res) })

Ответ 6

Некоторые файлы js поступают из Интернета или библиотеки, они не написаны сами. Код, который они получают, изменяется следующим образом:

var queryString = document.location.search.substring(1);
var params = PDFViewerApplication.parseQueryString(queryString);
var file = 'file' in params ? params.file : DEFAULT_URL;

Этот метод делает файлы js неизменными (сохраняйте независимость) и правильно передавайте переменные!