我有一个页面显示目录中的文件列表.当用户单击“下载”按钮时,所有这些文件都将压缩到一个文件中,然后提供下载.我知道如何在点击按钮时将该文件发送到浏览器,并且我知道如何重新加载当前页面(或重定向到另一个页面),但是是否可以在同一步骤中同时执行?或者通过下载链接重定向到不同的页面会更有意义吗?
我的下载是使用Flask API的send_from_directory启动的.相关测试代码:
@app.route('/download',methods=['GET','POST']) def download(): error=None # ... if request.method == 'POST': if download_list == None or len(download_list) < 1: error = 'No files to download' else: timestamp = dt.now().strftime('%Y%m%d:%H%M%S') zfname = 'reports-' + str(timestamp) + '.zip' zf = zipfile.ZipFile(downloaddir + zfname,'a') for f in download_list: zf.write(downloaddir + f,f) zf.close() # TODO: remove zipped files,move zip to archive return send_from_directory(downloaddir,zfname,as_attachment=True) return render_template('download.html',error=error,download_list=download_list)
更新:作为解决方法,我现在正在加载一个新的页面与按钮单击,这让用户启动下载(使用send_from_directory),然后返回到更新的列表.
解决方法
您是否在前端Web服务器(如Nginx或apache)上运行烧瓶应用程序(这将是处理文件下载的最佳方式).如果您使用Nginx,您可以使用
‘X-Accel-Redirect’标题.对于这个例子,我将使用目录/ srv / static / reports作为您正在创建zip文件的目录,并希望将它们提供给它们.
Nginx.conf
在服务器部分
server { # add this to your current server config location /reports/ { internal; root /srv/static; } }
你的烧瓶方法
发送头到Nginx到服务器
from flask import make_response @app.route('/download','POST']) def download(): error=None # .. if request.method == 'POST': if download_list == None or len(download_list) < 1: error = 'No files to download' return render_template('download.html',download_list=download_list) else: timestamp = dt.now().strftime('%Y%m%d:%H%M%S') zfname = 'reports-' + str(timestamp) + '.zip' zf = zipfile.ZipFile(downloaddir + zfname,'a') for f in download_list: zf.write(downloaddir + f,f) zf.close() # TODO: remove zipped files,move zip to archive # tell Nginx to server the file and where to find it response = make_response() response.headers['Cache-Control'] = 'no-cache' response.headers['Content-Type'] = 'application/zip' response.headers['X-Accel-Redirect'] = '/reports/' + zf.filename return response
如果您使用apache,可以使用其sendfile指令http://httpd.apache.org/docs/2.0/mod/core.html#enablesendfile