下载在Flask中即时生成的文件的首选方法

时间:2011-03-23 19:02:14

标签: html download flask

我有一个页面,显示目录中的文件列表。当用户单击“下载”按钮时,所有这些文件都压缩为单个文件,然后提供下载。我知道如何在单击按钮时将此文件发送到浏览器,并且我知道如何重新加载当前页面(或重定向到另一个页面),但是可以在同一步骤中执行这两个操作吗?或者通过下载链接重定向到另一个页面会更有意义吗?

我的下载是使用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)。

1 个答案:

答案 0 :(得分:7)

您是否在前端Web服务器(如nginx或apache)后面运行烧瓶应用程序(这将是处理文件下载的最佳方式)。如果您使用的是nginx,则可以使用'X-Accel-Redirect'标头。对于此示例,我将使用目录/srv/static/reports作为您正在创建zip文件的目录,并希望将其提供给它们。

<强> nginx.conf

server部分

server {
  # add this to your current server config
  location /reports/ {
    internal;
    root /srv/static;
  }
}

你的烧瓶方法

将标头发送到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

如果你正在使用apache,你可以使用他们的sendfile指令http://httpd.apache.org/docs/2.0/mod/core.html#enablesendfile