HOWTO · Flask
使用 Flask 下载文件
通过这个解释,我们将学习如何在 Flask 中的 send_file 函数的帮助下创建一个可下载的链接以将文件下载为附件。
本页内容
要让 Flask 页面中的链接下载文件,请定义一个返回 send_file(path, as_attachment=True) 的路由,再用 url_for 将模板链接指向该路由。文件必须位于路由所使用的路径下。
通过 Flask 下载路由返回文件
send_file 会创建包含文件的响应。视图函数必须返回该响应;如果调用 send_file 时没有使用 return,Flask 就无法获得预期的响应。设置 as_attachment=True 后,Flask 会将文件作为附件发送,浏览器便会提示下载,而不是将它当作页面显示。
从模板链接到下载路由
使用 url_for 并传入路由的端点名称。默认情况下,Flask 会将视图函数名用作端点,因此下面的链接和函数都使用 download_file。URL 路径(/download)和端点名称是两个不同的概念:Flask 渲染模板时,url_for 会查找端点。GET 链接无法弥补端点拼写错误或端点未注册的问题。
模板应放在与 app.py 同级、名为 templates 的文件夹中:
本节中的代码以及显示的标签或输出仍为英文。
<h2>Download the sample file</h2>
<p><a href="{{ url_for('download_file') }}">Download</a></p>
使用可靠的文件路径和附件设置
从 app.root_path 构建路径,使路径以应用程序目录为基准,而不受 shell 当前工作目录影响。这个本地示例会在 app.py 旁创建一个小型文本文件;使用时,请将其替换为你要提供的文件路径。不要从 URL 或表单接收任意文件系统路径,再直接传给 send_file。
默认情况下,下载附件的文件名取自路径,因此此示例会将文件作为 sample.txt 提供。如果存储时使用的名称与下载名称不同,可以为 send_file 传入明确的 download_name 值。请确保所选路径由你控制,并在发送文件前确认文件可用;根据可信的应用程序设置构造路径,比使用访客提供的路径更容易管理。
将以下内容保存为 app.py。它会在应用程序旁创建模板和示例文件,然后使用 Flask 的测试客户端发起请求,无需启动服务器进程:
本节中的代码以及显示的标签或输出仍为英文。
from pathlib import Path
from flask import Flask, render_template, send_file
app = Flask(__name__)
template_dir = Path(app.root_path) / "templates"
template_dir.mkdir(exist_ok=True)
(template_dir / "index.html").write_text(
'<p><a href="{{ url_for(\'download_file\') }}">Download</a></p>',
encoding="utf-8",
)
SAMPLE_FILE = Path(app.root_path) / "sample.txt"
SAMPLE_FILE.write_text("A file served by Flask.\n", encoding="utf-8")
@app.route("/")
def index():
return render_template("index.html")
@app.route("/download")
def download_file():
return send_file(SAMPLE_FILE, as_attachment=True)
if __name__ == "__main__":
with app.test_client() as client:
print(client.get("/").get_data(as_text=True).strip())
response = client.get("/download")
print(response.status_code)
print(response.headers["Content-Disposition"])
print(response.get_data(as_text=True), end="")
模板会将 download_file 解析为 /download,测试客户端也会请求该路由。运行脚本时,它会打印渲染出的链接、响应状态、附件标头和文件内容。附件标头可用于确认浏览器收到的是下载响应;检查响应正文则可确认发送的是所选文件。
运行并验证完整示例
如果项目环境尚未安装 Flask,请先安装,然后运行 python app.py,在本地检查渲染出的链接和下载响应。若要在浏览器中尝试相同的路由,请使用 flask --app app run 启动 Flask 开发服务器,打开 http://127.0.0.1:5000/,再选择链接文字 Download(该示例中的链接文字保留为英文)。浏览器应会下载 sample.txt;直接访问 /download 也会返回同一个附件。按 Ctrl+C 停止服务器。调试模式仅用于本地开发;不要在可从公网访问的服务器上启用交互式调试器。