Flask 是一个轻量级的 Web 应用框架,它使用 Jinja2 作为模板引擎。Jinja2 是一个现代的、设计友好的模板语言,用于将 Python 代码和 HTML 分离,使得 Web 应用更加易于维护和扩展。下面将详细介绍 Jinja2 的基本语法,包括 if
、for
等常用语句。
1. 变量
在 Jinja2 中,你可以使用 {{ variable }}
语法来输出变量。例如,如果你在 Flask 视图函数中传递了一个名为 name
的变量,你可以在模板中这样输出它:
Hello, {{ name }}!
2. 注释
在 Jinja2 中,注释使用 {# ... #}
语法。这些注释不会在渲染的 HTML 中显示。
{# 这是一个注释 #}
3. 控制结构
if 语句
if
语句用于条件判断,基本语法如下:
{% if condition %}
...
{% elif condition %}
...
{% else %}
...
{% endif %}
例如:
{% if user %}
Hello, {{ user.username }}!
{% else %}
Hello, Guest!
{% endif %}
for 循环
for
循环用于遍历序列,基本语法如下:
{% for item in sequence %}
{{ loop.index }}: {{ item }}
{% endfor %}
loop.index
表示当前迭代的索引(从 1 开始),loop.index0
表示从 0 开始的索引。loop.first
、loop.last
分别用于判断是否是第一次或最后一次迭代。
例如,遍历一个用户列表:
<ul>
{% for user in users %}
<li>{{ user.username }}</li>
{% endfor %}
</ul>
4. 宏
宏(Macro)类似于 Python 中的函数,可以用来重用模板代码。定义宏使用 macro
标签,使用宏使用 call
标签。
{% macro render_user(user) %}
<li>{{ user.username }}</li>
{% endmacro %}
<ul>
{% for user in users %}
{{ render_user(user) }}
{% endfor %}
</ul>
5. 模板继承
Jinja2 支持模板继承,允许你创建一个基本的模板,其他模板可以从中继承并覆盖特定的块。
首先,创建一个基础模板,并定义可以被子模板覆盖的块:
<!-- base.html -->
<html>
<head>
<title>{% block title %}My Webpage{% endblock %}</title>
</head>
<body>
{% block body %}
<p>This is the base template.</p>
{% endblock %}
</body>
</html>
然后,创建一个子模板,并扩展基础模板:
<!-- index.html -->
{% extends "base.html" %}
{% block title %}Index{% endblock %}
{% block body %}
<p>This is the index page.</p>
{% endblock %}
6. 包含
使用 include
标签可以在模板中包含其他模板的内容。
{% include 'footer.html' %}
7. 过滤器
过滤器用于对变量进行格式化。它们通过管道符号 |
应用。
{{ name|capitalize }}
这会将 name
变量的值转换为首字母大写的形式。
8. CSRF 保护
在 Flask 表单中,通常使用 {{ form.hidden_tag() }}
来生成 CSRF 令牌,以防止跨站请求伪造攻击。
<form method="post">
{{ form.hidden_tag() }}
<!-- 表单其他字段 -->
</form>
生成 CSRF 令牌
在表单中使用 {{ form.hidden_tag() }}
会自动包含 CSRF 令牌,该令牌用于验证表单提交的请求是否来自于应用程序的合法用户。
验证 CSRF 令牌
Flask-WTF 扩展提供了 CSRF 保护功能,并在接收到 POST、PUT、PATCH 或 DELETE 请求时自动验证 CSRF 令牌的有效性。如果 CSRF 令牌验证失败,Flask 会抛出 CSRFError
异常。
配置 CSRF 保护
在 Flask 应用中启用 CSRF 保护非常简单,只需在应用配置中设置 WTF_CSRF_ENABLED
为 True
即可:
app = Flask(__name__)
app.config['WTF_CSRF_ENABLED'] = True
客户端 Ajax 请求的 CSRF 保护
当使用 Ajax 发送 POST 请求时,需要确保将 CSRF 令牌包含在请求中。通常的做法是将令牌存储在页面的某个地方(比如一个 meta
标签中),然后在 Ajax 请求中将其添加到请求头中。
<meta name="csrf-token" content="{{ csrf_token() }}">
然后在发起 Ajax 请求时,将令牌添加到请求头中:
var csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': csrfToken
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
这样就能确保 Ajax 请求中包含了正确的 CSRF 令牌,从而保护应用免受 CSRF 攻击。