I have a page that displays a list of files in a directory. When the user clicks on the Download button, all of these files are zipped into a single file, which is then offered for download. I know how to send this file to the browser when the button is clicked, and I know how to reload the current page (or redirect to a different one), but is it possible to do both in the same step? Or would it make more sense to redirect to a different page with a download link?
我有一个页面,显示目录中的文件列表。当用户单击“下载”按钮时,所有这些文件都压缩为单个文件,然后提供下载。我知道如何在单击按钮时将此文件发送到浏览器,并且我知道如何重新加载当前页面(或重定向到另一个页面),但是是否可以在同一步骤中执行这两个操作?或者通过下载链接重定向到不同的页面会更有意义吗?
My download is initiated with the Flask API's send_from_directory
. Relevant test code:
我的下载是使用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)
Update: As a workaround, I am now loading a new page with the button click, which lets the user initiate the download (using send_from_directory
) before returning to the updated listing.
更新:作为一种解决方法,我现在正在加载一个单击按钮的新页面,这允许用户在返回更新列表之前启动下载(使用send_from_directory)。
1 个解决方案
#1
7
Are you running the flask app behind a front end web server such as nginx or apache (which would be the best way to handle the downloading of files). If you're using nginx you can use the 'X-Accel-Redirect' header. For this example I'll use the directory /srv/static/reports
as the directory you're creating the zipfiles in and wanting to serve them out of.
您是否在前端Web服务器(如nginx或apache)后面运行烧瓶应用程序(这将是处理文件下载的最佳方式)。如果您使用的是nginx,则可以使用“X-Accel-Redirect”标题。对于这个例子,我将使用目录/ srv / static / reports作为你正在创建zipfiles的目录,并希望将它们提供给它们。
nginx.conf
in the server
section
在服务器部分
server {
# add this to your current server config
location /reports/ {
internal;
root /srv/static;
}
}
your flask method
你的烧瓶方法
send the header to nginx to server
将标头发送到nginx到服务器
from flask import make_response
@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'
return render_template('download.html', error=error, 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
If you're using apache, you can use their sendfile directive http://httpd.apache.org/docs/2.0/mod/core.html#enablesendfile
如果你正在使用apache,你可以使用他们的sendfile指令http://httpd.apache.org/docs/2.0/mod/core.html#enablesendfile
#1
7
Are you running the flask app behind a front end web server such as nginx or apache (which would be the best way to handle the downloading of files). If you're using nginx you can use the 'X-Accel-Redirect' header. For this example I'll use the directory /srv/static/reports
as the directory you're creating the zipfiles in and wanting to serve them out of.
您是否在前端Web服务器(如nginx或apache)后面运行烧瓶应用程序(这将是处理文件下载的最佳方式)。如果您使用的是nginx,则可以使用“X-Accel-Redirect”标题。对于这个例子,我将使用目录/ srv / static / reports作为你正在创建zipfiles的目录,并希望将它们提供给它们。
nginx.conf
in the server
section
在服务器部分
server {
# add this to your current server config
location /reports/ {
internal;
root /srv/static;
}
}
your flask method
你的烧瓶方法
send the header to nginx to server
将标头发送到nginx到服务器
from flask import make_response
@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'
return render_template('download.html', error=error, 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
If you're using apache, you can use their sendfile directive http://httpd.apache.org/docs/2.0/mod/core.html#enablesendfile
如果你正在使用apache,你可以使用他们的sendfile指令http://httpd.apache.org/docs/2.0/mod/core.html#enablesendfile