use*_*766 58 javascript python variables jinja2
假设我有一个Python变量:
list_of_items = ['1','2','3','4','5']
Run Code Online (Sandbox Code Playgroud)
我通过渲染HTML将它传递给Jinja,我还在JavaScript中使用了一个函数somefunction(variable).我试图通过每个项目list_of_items.我试过这样的事情:
{% for item in list_of_items %}
<span onclick="somefunction({{item}})">{{item}}</span><br>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
是否可以将列表从Python传递给JavaScript,还是应该在循环中逐个传递列表中的每个项目?我怎样才能做到这一点?
mde*_*ous 90
要将一些上下文数据传递给javascript代码,您必须以javascript(即JSON)"理解"的方式对其进行序列化.您还需要使用safeJinja过滤器将其标记为安全,以防止您的数据被htmlescaped.
你可以通过这样做来实现这一点:
import json
@app.route('/')
def my_view():
data = [1, 'foo']
return render_template('index.html', data=json.dumps(data))
Run Code Online (Sandbox Code Playgroud)
<script type="text/javascript">
function test_func(data) {
console.log(data);
}
test_func({{ data|safe }})
</script>
Run Code Online (Sandbox Code Playgroud)
因此,要实现您想要的内容(遍历项目列表并将其传递给javascript函数),您需要单独序列化列表中的每个项目.您的代码将如下所示:
import json
@app.route('/')
def my_view():
data = [1, "foo"]
return render_template('index.html', data=map(json.dumps, data))
Run Code Online (Sandbox Code Playgroud)
{% for item in data %}
<span onclick=someFunction({{ item|safe }});>{{ item }}</span>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
在我的例子中,我使用Flask,我不知道你正在使用什么框架,但你明白了,你必须使它适合你使用的框架.
永远不要使用用户提供的数据,只能用可靠的数据做到这一点!
否则,您会将应用程序暴露给XSS漏洞!
God*_*ith 27
我使用Flask时遇到了类似的问题,但我不必诉诸JSON.我只是通过一个列表letters = ['a','b','c']与render_template('show_entries.html', letters=letters)和设置
var letters = {{ letters|safe }}
Run Code Online (Sandbox Code Playgroud)
在我的JavaScript代码中.Jinja2替换{{ letters }}为['a','b','c'],其中javascript被解释为字符串数组.
Mar*_*ery 14
你可以用 Jinja 的tojson过滤器来做到这一点,它
将结构转储到 JSON,以便
<script>在 HTML 中的任何位置的标签 [和] 中使用都是安全的,但双引号属性除外。
例如,在您的 Python 中,编写:
some_template.render(list_of_items=list_of_items)
Run Code Online (Sandbox Code Playgroud)
...或者,在 Flask 端点的上下文中:
return render_template('your_template.html', list_of_items=list_of_items)
Run Code Online (Sandbox Code Playgroud)
然后在你的模板中,写下这个:
{% for item in list_of_items %}
<span onclick='somefunction({{item | tojson}})'>{{item}}</span><br>
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
(请注意,该onclick属性是单引号。这是必要的,因为在其输出中|tojson转义'字符而不是"字符,这意味着它可以安全地用于单引号 HTML 属性中,但不能用于双引号属性。)
或者,要list_of_items在内联脚本中使用而不是 HTML 属性,请编写以下内容:
<script>
const jsArrayOfItems = {{list_of_items | tojson}};
// ... do something with jsArrayOfItems in JavaScript ...
</script>
Run Code Online (Sandbox Code Playgroud)
不要json.dumps在 Python 代码中使用JSON 编码变量并将生成的 JSON 文本传递给模板。这会为某些字符串值产生不正确的输出,并且如果您尝试对用户提供的值进行编码,则会将您暴露给 XSS。这是因为 Python 的内置json.dumps不会转义像<和>这样的字符(需要转义以安全地将值模板化为 inline <script>s,如https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for 所述-contents-of-script-elements)或单引号(需要转义以安全地将值模板化为单引号 HTML 属性)。
如果您使用 Flask,请注意 Flask 注入自定义tojson过滤器而不是使用 Jinja 的版本。但是,上面写的所有内容仍然适用。这两个版本的行为几乎相同;Flask 只允许一些在 Jinja 版本中不可用的特定于应用程序的配置。
为了补充所选的答案,我一直在测试一个新选项,该选项也使用 jinja2 和 Flask 工作:
@app.route('/')
def my_view():
data = [1, 2, 3, 4, 5]
return render_template('index.html', data=data)
Run Code Online (Sandbox Code Playgroud)
模板:
<script>
console.log( {{ data | tojson }} )
</script>
Run Code Online (Sandbox Code Playgroud)
渲染模板的输出:
<script>
console.log( [1, 2, 3, 4] )
</script>
Run Code Online (Sandbox Code Playgroud)
可以safe添加,但也想{{ data | tojson | safe }}避免 html 转义,但它也可以在没有转义的情况下工作。
| 归档时间: |
|
| 查看次数: |
78836 次 |
| 最近记录: |