Jinja 未在块内执行 python 代码的问题
Problems with Jinja not executing python code within a block
我有一个基本的网络应用程序 - 一个博客 - 我正在尝试使用 Flask 创建。
我正尝试在我的 index.html
中使用 {{ url_for('static', filename='vendor/fontawesome-free/css/all.min.css') }}
来创建动态 url。但是,我不断收到 GET 请求错误,因为 Jinja 未将其识别为 python 代码,并且 Flask 正在尝试使用逐字调用创建 url。
这是一个错误示例:
"GET /%7B%20%7Burl_for(%22static%22,%20filename=%22vendor/bootstrap/css/bootstrap.min.css%22)%20%7D%7D HTTP/1.1" 404
问题不在于 url_for() 调用或我 directory/inclusion 的正确静态和模板文件夹的结构,因为使用
with app.test_request_context():
print(url_for('static', filename='vendor/fontawesome-free/css/all.min.css'))
在我的 main.py
文件中打印出正确的路径。
此外,Jinja 已正确安装并正常工作,{% include "header.html" %}
和 {% include "footer.html" %}
都可以正常工作,因为创建 url 的尝试都在这些文件中。
这是我的 main.py
from flask import Flask,render_template, url_for
import jinja2
app = Flask(__name__)
@app.route('/')
def root():
return render_template('index.html')
with app.test_request_context():
print(url_for('static', filename='vendor/fontawesome-free/css/all.min.css'))
if __name__=='__main__':
app.run(debug=True)
这是index.html
的相关部分
{% include "header.html"%}
<!-- Page Header -->
<header class="masthead" style="background-image: url('static/img/home-bg.jpg')">
...
</header>
<!-- Main Content -->
<div class="container">
...
</div>
{% include "footer.html"%}
这是 footer.html
:
<!-- Footer -->
<footer>
...
</footer>
<!-- Bootstrap core JavaScript -->
<script src="{{ url_for('static', filename='vendor/jquery/jquery.min.js') }}"></script>
<script src="{{ url_for('static', filename='vendor/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
<!-- Custom scripts for this template -->
<script src="{{ url_for('static', filename='js/clean-blog.min.js') }}"></script>
</body>
</html>
这是 header.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Clean Blog - Start Bootstrap Theme</title>
<!-- Bootstrap core CSS -->
<link href="{{ url_for('static', filename='vendor/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet">
<!-- Custom fonts for this template -->
<link href="{{ url_for('static', filename='vendor/fontawesome-free/css/all.min.css')}} " rel="stylesheet" type="text/css">
<link href='https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<!-- Custom styles for this template -->
<link href="{{ url_for('static', filename='css/clean-blog.min.css')}} " rel="stylesheet">
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-light fixed-top" id="mainNav">
...
</nav>
最后一点,在创建动态 url 和进行静态引用之前,所有 CSS/JS 文件都正确呈现。
编辑
以下代码在页面上正确呈现 url。
<h1>{{url_for('static', filename='vendor/bootstrap/css/bootstrap.min.css', _external=True)}}</h1>
只有当我将其包装为字符串时,它才不再将其作为代码提取。
在您粘贴到问题中的内容中,Jinja 表达式前面的两个 {
标记之间有一个 Unicode zero-width non-joiner 字符。也就是说,如果我从 footer.html
:
复制这一行
<script src="{{ url_for('static', filename='vendor/jquery/jquery.min.js') }}"></script>
并从中生成一个 hexdump,我明白了:
00000000: 2020 3c73 6372 6970 7420 7372 633d 227b <script src="{
00000010: e280 8c7b 2075 726c 5f66 6f72 2827 7374 ...{ url_for('st
00000020: 6174 6963 272c 2066 696c 656e 616d 653d atic', filename=
00000030: 2776 656e 646f 722f 6a71 7565 7279 2f6a 'vendor/jquery/j
00000040: 7175 6572 792e 6d69 6e2e 6a73 2729 207d query.min.js') }
00000050: 7d22 3e3c 2f73 6372 6970 743e 0a }"></script>.
查看偏移量 x10
,我们在其中看到 e2 80 8c
;这是U+200c的UTF-8编码:
>>> "\u200c".encode()
b'\xe2\x80\x8c'
如果我从你的源代码中删除那些无关的字符,一切都会正常工作:
$ curl -s localhost:5000 | grep static
<link href="/static/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/vendor/fontawesome-free/css/all.min.css " rel="stylesheet" type="text/css">
<link href="/static/css/clean-blog.min.css " rel="stylesheet">
<header class="masthead" style="background-image: url('static/img/home-bg.jpg')">
This is a test /static/foo/bar
<script src="/static/vendor/jquery/jquery.min.js"></script>
<script src="/static/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="/static/js/clean-blog.min.js"></script>
我有一个基本的网络应用程序 - 一个博客 - 我正在尝试使用 Flask 创建。
我正尝试在我的 index.html
中使用 {{ url_for('static', filename='vendor/fontawesome-free/css/all.min.css') }}
来创建动态 url。但是,我不断收到 GET 请求错误,因为 Jinja 未将其识别为 python 代码,并且 Flask 正在尝试使用逐字调用创建 url。
这是一个错误示例:
"GET /%7B%20%7Burl_for(%22static%22,%20filename=%22vendor/bootstrap/css/bootstrap.min.css%22)%20%7D%7D HTTP/1.1" 404
问题不在于 url_for() 调用或我 directory/inclusion 的正确静态和模板文件夹的结构,因为使用
with app.test_request_context():
print(url_for('static', filename='vendor/fontawesome-free/css/all.min.css'))
在我的 main.py
文件中打印出正确的路径。
此外,Jinja 已正确安装并正常工作,{% include "header.html" %}
和 {% include "footer.html" %}
都可以正常工作,因为创建 url 的尝试都在这些文件中。
这是我的 main.py
from flask import Flask,render_template, url_for
import jinja2
app = Flask(__name__)
@app.route('/')
def root():
return render_template('index.html')
with app.test_request_context():
print(url_for('static', filename='vendor/fontawesome-free/css/all.min.css'))
if __name__=='__main__':
app.run(debug=True)
这是index.html
{% include "header.html"%}
<!-- Page Header -->
<header class="masthead" style="background-image: url('static/img/home-bg.jpg')">
...
</header>
<!-- Main Content -->
<div class="container">
...
</div>
{% include "footer.html"%}
这是 footer.html
:
<!-- Footer -->
<footer>
...
</footer>
<!-- Bootstrap core JavaScript -->
<script src="{{ url_for('static', filename='vendor/jquery/jquery.min.js') }}"></script>
<script src="{{ url_for('static', filename='vendor/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
<!-- Custom scripts for this template -->
<script src="{{ url_for('static', filename='js/clean-blog.min.js') }}"></script>
</body>
</html>
这是 header.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">
<title>Clean Blog - Start Bootstrap Theme</title>
<!-- Bootstrap core CSS -->
<link href="{{ url_for('static', filename='vendor/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet">
<!-- Custom fonts for this template -->
<link href="{{ url_for('static', filename='vendor/fontawesome-free/css/all.min.css')}} " rel="stylesheet" type="text/css">
<link href='https://fonts.googleapis.com/css?family=Lora:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800' rel='stylesheet' type='text/css'>
<!-- Custom styles for this template -->
<link href="{{ url_for('static', filename='css/clean-blog.min.css')}} " rel="stylesheet">
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-light fixed-top" id="mainNav">
...
</nav>
最后一点,在创建动态 url 和进行静态引用之前,所有 CSS/JS 文件都正确呈现。
编辑
以下代码在页面上正确呈现 url。
<h1>{{url_for('static', filename='vendor/bootstrap/css/bootstrap.min.css', _external=True)}}</h1>
只有当我将其包装为字符串时,它才不再将其作为代码提取。
在您粘贴到问题中的内容中,Jinja 表达式前面的两个 {
标记之间有一个 Unicode zero-width non-joiner 字符。也就是说,如果我从 footer.html
:
<script src="{{ url_for('static', filename='vendor/jquery/jquery.min.js') }}"></script>
并从中生成一个 hexdump,我明白了:
00000000: 2020 3c73 6372 6970 7420 7372 633d 227b <script src="{
00000010: e280 8c7b 2075 726c 5f66 6f72 2827 7374 ...{ url_for('st
00000020: 6174 6963 272c 2066 696c 656e 616d 653d atic', filename=
00000030: 2776 656e 646f 722f 6a71 7565 7279 2f6a 'vendor/jquery/j
00000040: 7175 6572 792e 6d69 6e2e 6a73 2729 207d query.min.js') }
00000050: 7d22 3e3c 2f73 6372 6970 743e 0a }"></script>.
查看偏移量 x10
,我们在其中看到 e2 80 8c
;这是U+200c的UTF-8编码:
>>> "\u200c".encode()
b'\xe2\x80\x8c'
如果我从你的源代码中删除那些无关的字符,一切都会正常工作:
$ curl -s localhost:5000 | grep static
<link href="/static/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/vendor/fontawesome-free/css/all.min.css " rel="stylesheet" type="text/css">
<link href="/static/css/clean-blog.min.css " rel="stylesheet">
<header class="masthead" style="background-image: url('static/img/home-bg.jpg')">
This is a test /static/foo/bar
<script src="/static/vendor/jquery/jquery.min.js"></script>
<script src="/static/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="/static/js/clean-blog.min.js"></script>