在 returns `send_file` 的 flask 函数中,代码不会在后续请求中出现 运行,但文件仍在下载。为什么?
In a flask function which returns `send_file`, the code doesn't appear to run on subsequent requests, yet the file still downloads. Why?
我正在使用具有以下路径的 Flask 代码:
@app.route('/download')
def download_file():
path = "certificate.docx"
print("certificate printed")
print(os.getcwd())
return send_file(path, as_attachment=True)
HTML代码:
<p>
<a href="{{ url_for('.download_file') }}">Download</a>
</p>
正在执行这段代码以下载名为 certificate.docx
.
的文件
问题是函数 download_file()
中的打印语句实际上并没有被执行,但它仍然允许我下载文件。
我假设您希望打印语句显示在您的 HTML 中。如果这不是您要找的,我深表歉意。
首先,您的示例中 print 所做的是在服务器上输出文本,因此文本永远不会发送到您的 HTML。
要向您的 HTML 发送消息,您可以从 Flask 导入 flash
。 flash
函数将向您的 HTML 发送一条消息,您可以在其中使用 get_flashed_messages()
.
接收代码
例子
这是改编自 Flask Docs 的示例。
下面我们做一些事情。
- 我们使用
flash
而不是 print
。传递给 flash
的第一个参数是消息。 ("certificate printed"
or os.getcwd()
) 第二个参数是消息的类别。 ( "download_file"
) 注意类别可以完全任意,只要在模板中使用相同的类别即可。
- 在 HTML 中的 link 下方。我们调用
get_flashed_messages
并将其赋值给一个变量download_msgs
。本例中唯一的参数是 category_filter=["download_file"]
。这将获取我们之前使用 flash
发送的所有消息,并仅保留具有 "download_file"
类别的消息。
- 我们用
{% if download_msgs %}
检查消息,用 {% for message in download_msgs %}
循环消息,并显示每条消息。
烧瓶:
from flask import Flask, flash, send_file
app = Flask(__name__)
@app.route('/download')
def download_file():
path = "certificate.docx"
flash("certificate printed", "download_file")
flash(os.getcwd(), "download_file")
return send_file(path, as_attachment=True)
HTML:
<p>
<a href="{{ url_for('.download_file') }}">Download</a>
{% with download_msgs = get_flashed_messages(category_filter=["download_file"]) %}
{% if download_msgs %}
<ul class=flashes>
{% for message in download_msgs %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</p>
这个例子很粗糙,但我希望它能回答你的问题
总结
- 要从您的 Flask 应用向您的 HTML 代码发送消息,您可以使用 Flask 应用中的
flash
功能。
- 要从您的 Flask 应用接收消息到您的 HTML 代码,您可以在 HTML 代码中使用
get_flashed_messages
函数。
- 您可以使用类别来区分闪烁的消息。在你的烧瓶应用程序中使用
flash
的第二个参数。在 HTML 代码中使用 get_flashed_messages
的 category_filter 关键字参数。
这个问题很可能是由 Flask 内置的缓存引起的。这设置了 Cache-Control
header,并适用于 Flask 提供的静态文件,也适用于 send_file
和 send_from_directory
函数。 (reference).
这将解释文件下载的行为,但打印语句不是 运行。事实上,该请求甚至不会到达服务器。
您可以在开发工具的网络选项卡上将其可视化:
您可以通过在您的应用中设置以下配置变量来禁用此功能:
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = -1
-1
值禁用缓存。
您可能必须实际清除浏览器缓存才能使此设置生效,或者更改 /download
端点的 URL,尽管这很不方便。
设置后请注意区别:
我正在使用具有以下路径的 Flask 代码:
@app.route('/download')
def download_file():
path = "certificate.docx"
print("certificate printed")
print(os.getcwd())
return send_file(path, as_attachment=True)
HTML代码:
<p>
<a href="{{ url_for('.download_file') }}">Download</a>
</p>
正在执行这段代码以下载名为 certificate.docx
.
问题是函数 download_file()
中的打印语句实际上并没有被执行,但它仍然允许我下载文件。
我假设您希望打印语句显示在您的 HTML 中。如果这不是您要找的,我深表歉意。
首先,您的示例中 print 所做的是在服务器上输出文本,因此文本永远不会发送到您的 HTML。
要向您的 HTML 发送消息,您可以从 Flask 导入 flash
。 flash
函数将向您的 HTML 发送一条消息,您可以在其中使用 get_flashed_messages()
.
例子
这是改编自 Flask Docs 的示例。
下面我们做一些事情。
- 我们使用
flash
而不是print
。传递给flash
的第一个参数是消息。 ("certificate printed"
oros.getcwd()
) 第二个参数是消息的类别。 ("download_file"
) 注意类别可以完全任意,只要在模板中使用相同的类别即可。 - 在 HTML 中的 link 下方。我们调用
get_flashed_messages
并将其赋值给一个变量download_msgs
。本例中唯一的参数是category_filter=["download_file"]
。这将获取我们之前使用flash
发送的所有消息,并仅保留具有"download_file"
类别的消息。 - 我们用
{% if download_msgs %}
检查消息,用{% for message in download_msgs %}
循环消息,并显示每条消息。
烧瓶:
from flask import Flask, flash, send_file
app = Flask(__name__)
@app.route('/download')
def download_file():
path = "certificate.docx"
flash("certificate printed", "download_file")
flash(os.getcwd(), "download_file")
return send_file(path, as_attachment=True)
HTML:
<p>
<a href="{{ url_for('.download_file') }}">Download</a>
{% with download_msgs = get_flashed_messages(category_filter=["download_file"]) %}
{% if download_msgs %}
<ul class=flashes>
{% for message in download_msgs %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
</p>
这个例子很粗糙,但我希望它能回答你的问题
总结
- 要从您的 Flask 应用向您的 HTML 代码发送消息,您可以使用 Flask 应用中的
flash
功能。 - 要从您的 Flask 应用接收消息到您的 HTML 代码,您可以在 HTML 代码中使用
get_flashed_messages
函数。 - 您可以使用类别来区分闪烁的消息。在你的烧瓶应用程序中使用
flash
的第二个参数。在 HTML 代码中使用get_flashed_messages
的 category_filter 关键字参数。
这个问题很可能是由 Flask 内置的缓存引起的。这设置了 Cache-Control
header,并适用于 Flask 提供的静态文件,也适用于 send_file
和 send_from_directory
函数。 (reference).
这将解释文件下载的行为,但打印语句不是 运行。事实上,该请求甚至不会到达服务器。
您可以在开发工具的网络选项卡上将其可视化:
您可以通过在您的应用中设置以下配置变量来禁用此功能:
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = -1
-1
值禁用缓存。
您可能必须实际清除浏览器缓存才能使此设置生效,或者更改 /download
端点的 URL,尽管这很不方便。
设置后请注意区别: