Flask下载ZIP或RAR大文件——流式下载
发布时间:2021-12-03
公开文章
背景
Flask在send_from_directory()时遇到Zip文件传输一定大小就重新开始,一开始以为Ngix配置问题,在后来觉得是断点续传的问题,结果瞎搞一通,都没有搞定;最后,采用分段下载搞定。
基础
from flask import Flask, request, Response
app = Flask(__name__)
@app.route('/login', methods=["get", "post"], endpoint='login')
def login():
if request.method == "POST":
response = Response()
name = request.form.get("name")
pwd = request.form.get("pwd")
if name and pwd:
if name == '朱宇' and pwd == '123':
response.data = '登陆成功'
# 注意,我这里只是写个例子,不会拿明文的账号密码设置为cookie
response.set_cookie('name', '朱宇')
response.set_cookie('pwd', '123')
else:
response.data = '用户名或密码错误'
else:
response.data = '用户名或密码不能为空'
return response
elif request.method == 'GET':
# 我这里返回字符串表示一个页面,你完全可以写一个html页面,使用render_template这个方法返回
return 'login.html'
if __name__ == "__main__":
app.run(debug=True)
先要看懂上面这段代码,精彩的来了。
流式下载
@app.route('/downloadfile/', methods=['GET', 'POST'])
def downloadfile():
if request.method == 'GET':
fullfilename = request.args.get('filename')
# fullfilename = '/root/allfile/123.txt'
fullfilenamelist = fullfilename.split('/')
filename = fullfilenamelist[-1]
filepath = fullfilename.replace('/%s'%filename, '')
#普通下载
# response = make_response(send_from_directory(filepath, filename, as_attachment=True))
# response.headers["Content-Disposition"] = "attachment; filename={}".format(filepath.encode().decode('latin-1'))
#return send_from_directory(filepath, filename, as_attachment=True)
#流式读取
def send_file():
store_path = fullfilename
with open(store_path, 'rb') as targetfile:
while 1:
data = targetfile.read(20 * 1024 * 1024) # 每次读取20M
if not data:
break
yield data
response = Response(send_file(), content_type='application/octet-stream')
response.headers["Content-disposition"] = 'attachment; filename=%s' % filename # 如果不加上这行代码,导致下图的问题
return response
当没有文件名,和文件格式,遇到这种情况,打开F12,查看response.headers 与正常的比较。
总结
FLask总会在探索的过程中出现这样或那样的问题,这可能是较Django的缺点吧。