如何在模板中将数据从Flask传递到JavaScript ?

时间:2023-01-24 09:09:04

My app makes a call to an API that returns a dictionary. I want to pass information from this dict to JavaScript in the view. I am using the Google Maps API in the JS, specifically, so I'd like to pass it a list of tuples with the long/lat information. I know that render_template will pass these variables to the view so they can be used in HTML, but how could I pass them to JavaScript in the template?

我的应用程序调用一个返回字典的API。我想在视图中将此命令中的信息传递给JavaScript。我在JS中使用谷歌映射API,所以我想给它传递一个包含long/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)

6 个解决方案

#1


98  

You can use {{ variable }} anywhere in your template, not just in the HTML part. So this should work:

您可以在模板中的任何地方使用{{variable}},而不仅仅是在HTML部分。这应该工作:

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

Think of it as a two-stage process: First, Jinja (the template engine Flask uses) generates your text output. This gets sent to the user who executes the JavaScript he sees. If you want your Flask variable to be available in JavaScript as an array, you have to generate an array definition in your output:

可以将它看作是一个两阶段的过程:首先,Jinja (Flask使用的模板引擎)生成文本输出。这将发送给执行他看到的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 also offers more advanced constructs from Python, so you can shorten it to:

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>

You can also use for loops, if statements and many more, see the Jinja2 documentation for more.

您还可以使用for循环,if语句等等,更多信息请参见Jinja2文档。

Also have a look at ford's answer who points out the tojson filter which is an addition to Jinja2's standard set of filters.

还可以看看福特的答案,他指出了tojson过滤器,它是Jinja2的标准过滤器的补充。

#2


73  

The ideal way to go about getting pretty much any Python object into a JavaScript object is to use JSON. JSON is great as a format for transfer between systems, but sometimes we forget that it stands for JavaScript Object Notation. This means that injecting JSON into the template is the same as injecting JavaScript code that describes the object.

将几乎所有Python对象都放入JavaScript对象的理想方法是使用JSON。JSON作为系统间传输的一种格式非常棒,但有时我们忘记了它代表的是JavaScript对象表示法。这意味着将JSON注入模板与将描述对象的JavaScript代码注入模板是一样的。

Flask provides a Jinja filter for this: tojson dumps the structure to a JSON string and marks it safe so that Jinja does not autoescape it.

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>

This works for any Python structure that is JSON serializable:

这适用于任何JSON可序列化的Python结构:

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


5  

Using a data attribute on an HTML element avoids having to use inline scripting, which in turn means you can use stricter CSP rules for increased security.

在HTML元素上使用数据属性可以避免使用内联脚本,这意味着您可以使用更严格的CSP规则来提高安全性。

Specify a data attribute like so:

指定数据属性如下:

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

Then access it in a static JavaScript file like so:

然后在静态JavaScript文件中访问它,如下所示:

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

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

#4


4  

Alternatively you could add an endpoint to return your variable:

或者,您可以添加一个端点来返回您的变量:

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

Then do an XHR to retrieve it:

然后执行XHR检索:

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

#5


3  

Just another alternative solution for those who want to pass variables to a script which is sourced using flask, I only managed to get this working by defining the variables outside and then calling the script as follows:

对于那些希望将变量传递给使用flask的脚本的人来说,这是另一种解决方案。

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

If I input jinja variables in test123.js it doesn't work and you will get an error.

如果我在test123中输入jinja变量。它不工作,你会得到一个错误。

#6


0  

Some js files come from the web or library, they are not written by yourself. The code they get variable like this:

有些js文件来自web或库,它们不是自己编写的。他们得到的代码是这样的:

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

This method makes js files unchanged(keep independence), and pass variable correctly!

此方法使js文件保持不变(保持独立),并正确传递变量!

#1


98  

You can use {{ variable }} anywhere in your template, not just in the HTML part. So this should work:

您可以在模板中的任何地方使用{{variable}},而不仅仅是在HTML部分。这应该工作:

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

Think of it as a two-stage process: First, Jinja (the template engine Flask uses) generates your text output. This gets sent to the user who executes the JavaScript he sees. If you want your Flask variable to be available in JavaScript as an array, you have to generate an array definition in your output:

可以将它看作是一个两阶段的过程:首先,Jinja (Flask使用的模板引擎)生成文本输出。这将发送给执行他看到的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 also offers more advanced constructs from Python, so you can shorten it to:

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>

You can also use for loops, if statements and many more, see the Jinja2 documentation for more.

您还可以使用for循环,if语句等等,更多信息请参见Jinja2文档。

Also have a look at ford's answer who points out the tojson filter which is an addition to Jinja2's standard set of filters.

还可以看看福特的答案,他指出了tojson过滤器,它是Jinja2的标准过滤器的补充。

#2


73  

The ideal way to go about getting pretty much any Python object into a JavaScript object is to use JSON. JSON is great as a format for transfer between systems, but sometimes we forget that it stands for JavaScript Object Notation. This means that injecting JSON into the template is the same as injecting JavaScript code that describes the object.

将几乎所有Python对象都放入JavaScript对象的理想方法是使用JSON。JSON作为系统间传输的一种格式非常棒,但有时我们忘记了它代表的是JavaScript对象表示法。这意味着将JSON注入模板与将描述对象的JavaScript代码注入模板是一样的。

Flask provides a Jinja filter for this: tojson dumps the structure to a JSON string and marks it safe so that Jinja does not autoescape it.

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>

This works for any Python structure that is JSON serializable:

这适用于任何JSON可序列化的Python结构:

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


5  

Using a data attribute on an HTML element avoids having to use inline scripting, which in turn means you can use stricter CSP rules for increased security.

在HTML元素上使用数据属性可以避免使用内联脚本,这意味着您可以使用更严格的CSP规则来提高安全性。

Specify a data attribute like so:

指定数据属性如下:

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

Then access it in a static JavaScript file like so:

然后在静态JavaScript文件中访问它,如下所示:

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

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

#4


4  

Alternatively you could add an endpoint to return your variable:

或者,您可以添加一个端点来返回您的变量:

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

Then do an XHR to retrieve it:

然后执行XHR检索:

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

#5


3  

Just another alternative solution for those who want to pass variables to a script which is sourced using flask, I only managed to get this working by defining the variables outside and then calling the script as follows:

对于那些希望将变量传递给使用flask的脚本的人来说,这是另一种解决方案。

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

If I input jinja variables in test123.js it doesn't work and you will get an error.

如果我在test123中输入jinja变量。它不工作,你会得到一个错误。

#6


0  

Some js files come from the web or library, they are not written by yourself. The code they get variable like this:

有些js文件来自web或库,它们不是自己编写的。他们得到的代码是这样的:

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

This method makes js files unchanged(keep independence), and pass variable correctly!

此方法使js文件保持不变(保持独立),并正确传递变量!