我有一个小项目,必须回复一些文件.我知道使用nginx将是更好的决定,但文件非常小.
我的计划的一部分:
return send_file(os.path.join(filepath, filename))
Run Code Online (Sandbox Code Playgroud)
该行返回具有文件名的文件,download没有任何格式或类似的东西.已下载的文件名始终相同,不依赖于文件的真实名称.文件的真实名称是table.csv.如何以正确的文件名返回文件?
Mar*_*ers 24
您需要Content-Disposition: attachment; filename=....为浏览器设置HTTP标头以使用正确的文件名.
您可以send_file()通过设置as_attachment=True参数为您设置此标头.然后从传入的文件对象中获取文件名.使用attachment_filename参数显式设置不同的文件名:
return send_file(os.path.join(filepath, filename), as_attachment=True)
Run Code Online (Sandbox Code Playgroud)
as_attachment-True如果要使用Content-Disposition: attachment标题发送此文件,请设置为.attachment_filename- 附件的文件名,如果它与文件的文件名不同.
您可能希望使用该flask.send_from_directory()功能.该函数首先确保文件名存在(NotFound如果不存在则引发),并确保文件名不包含..可能用于"转义"目录的任何相关元素.将此用于从不受信任的来源获取的所有文件名:
return send_from_directory(filepath, filename, as_attachment=True)
Run Code Online (Sandbox Code Playgroud)
在某些情况下,文件名仍然不可见。要确定它,您应该设置“x-filename”标头并公开此标头。
from flask import send_file
response = send_file(absolute_image_path, mimetype='image/jpeg', attachment_filename=name, as_attachment=True)
response.headers["x-filename"] = name
response.headers["Access-Control-Expose-Headers"] = 'x-filename'
return response
Run Code Online (Sandbox Code Playgroud)
就我而言,设置as_attachment和attachment_filename无效,因为Content-Disposition: attachment不会出现在响应的客户端副本中。
如果启用了Flask-CORS,则可以将其初始化expose_headers为指定文件名的自定义标头(例如,“ x-suggested-filename ”)。然后将该标头添加到响应中。
# In file where the Flask app instance is initialized
app = Flask(__name__)
CORS(app, expose_headers=["x-suggested-filename"])
# In file with the download endpoint
result = send_file("/full/path/to/some/file",
mimetype="text/plain", # use appropriate type based on file
as_attachment=True,
conditional=False)
result.headers["x-suggested-filename"] = "use_this_filename.txt"
return result
Run Code Online (Sandbox Code Playgroud)
然后,在客户端下载代码中,您可以检查响应标头以从相同的自定义标头获取文件名:
# Using axios and FileSaver
let response = await axios.get(downloadUrl, downloadConfig);
let filename = response.headers["x-suggested-filename"];
FileSaver.saveAs(response.data, filename);
Run Code Online (Sandbox Code Playgroud)