如何在 Flask 中更改下载名称?

新手上路,请多包涵

我正在使用 Flask 的 send_file 在特定 URL 提供文件。但是,保存文件的名称始终是 URL 的最后一部分,如 download ,而不是真实名称 table.csv 。如何返回具有正确文件名的文件?

 @app.route("/download")
def download()
    return send_file("/path/to/table.csv")

原文由 faoxis 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.1k
2 个回答

您需要为浏览器设置 Content-Disposition: attachment; filename=.... HTTP 标头以使用正确的文件名。

您可以让 send_file() 通过设置 as_attachment=True 参数为您设置此标头。然后从您传入的文件对象中获取文件名。使用 download_name 参数显式设置不同的文件名:

 return send_file(os.path.join(filepath, filename), as_attachment=True)

来自 flask.send_file 文档

  • as_attachment – 向浏览器表明它应该提供保存文件而不是显示文件。
  • download_name – 保存文件时浏览器将使用的默认名称。默认为传递的文件名。

在 Flask 2.0 之前, download_name 被称为 attachment_filename

您可能想改用 flask.send_from_directory() 函数。该函数首先确保文件名存在(引发 NotFound 如果不存在),并确保文件名不包含任何 .. 可能用于“转义”的相关元素目录。将此用于从不受信任的来源获取的所有文件名:

 return send_from_directory(filepath, filename, as_attachment=True)

原文由 Martijn Pieters 发布,翻译遵循 CC BY-SA 4.0 许可协议

使用 Flask-CORS 时,默认设置 as_attachmentdownload_name 可能不起作用。您需要允许带有 expose_headersContent-Disposition 标头,否则它不会被发送到客户端。

 from flask import Flask, send_file
from flask_cors import CORS

app = Flask(__name__)
CORS(app, expose_headers=["Content-Disposition"])

 return send_file(
    "/path/to/file.txt",
    as_attachment=True,
    download_name="custom_name.txt"
)

如果要使用 JavaScript 下载和保存文件,一种选择是使用 axios 下载文件,然后使用 FileSaver.js 保存文件。默认情况下,FileSaver 将使用 Content-Disposition 标头 send_file 作为文件名。

 let response = await axios.get(downloadUrl, downloadConfig);
FileSaver.saveAs(response.data);

原文由 Gino Mempin 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题