You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Heroku文件系统中Flask应用生成文件的下载URL

Heroku dyno的临时文件系统不存在对外可直接访问的公网URL。整个文件系统是沙箱隔离的,只有运行在dyno内部的应用进程可以读写,没有默认的公网路径映射,所有对临时文件的访问都必须经过你的Flask应用路由处理,没有捷径可以走。

具体实现步骤
  • 后端编写带安全校验的下载路由
    直接在Flask中编写专用的下载接口,读取本地临时文件返回给客户端即可,参考代码:
from flask import send_file, abort
import os

# 替换为你自己存放生成临时文件的目录绝对路径
TEMP_FILE_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'temp_outputs')

@app.route('/get-download/<file_name>')
def temp_file_download(file_name):
    # 强制做路径合法性校验,防范路径遍历攻击
    target_path = os.path.abspath(os.path.join(TEMP_FILE_DIR, file_name))
    if not target_path.startswith(os.path.abspath(TEMP_FILE_DIR)):
        abort(403)
    if not os.path.exists(target_path):
        abort(404)
    # as_attachment=True会强制浏览器触发下载,而非直接打开文件
    return send_file(target_path, as_attachment=True)

不要省略路径校验步骤,否则攻击者可以构造../../敏感配置文件这类特殊文件名读取dyno内的隐私数据,存在严重安全隐患。

  • 前端按钮对接下载逻辑
    根据业务场景选择对应实现即可:
    • 如果文件在页面加载时就已经生成完成,直接把下载地址绑定到按钮点击事件上:
    <button onclick="location.href='/get-download/你生成的文件名.xlsx'">点击下载文件</button>
    
    • 如果文件是用户点击按钮后才异步生成的,在生成文件的接口返回值中携带对应下载路径,前端拿到后再触发下载:
    document.querySelector('#gen-and-download-btn').addEventListener('click', async () => {
      const resp = await fetch('/api/generate-temp-file', {method: 'POST'})
      const result = await resp.json()
      // 接口返回格式示例:{code:0, download_url: "/get-download/temp_123456.csv"}
      if (result.code === 0) {
        window.open(result.download_url, '_self')
      }
    })
    
踩坑提醒
  • 不建议通过配置Flask静态目录的方式直接映射临时文件目录,这种方式默认不带权限校验和路径防护,安全风险高,也无法自定义下载响应头。
  • 牢记dyno临时文件的生命周期特性:本地临时文件仅适合生成后立刻交付给用户下载的短时效场景,如果文件需要留存超过几分钟、或者用户可能在生成后间隔很久才下载,不要将文件存在dyno本地,生成后应转存到对象存储服务,否则极易出现用户点击下载时文件已被清理的404问题。
  • Heroku会在每日自动重启、部署发布、实例扩缩容时清空dyno本地文件,不要对本地文件的留存时长有任何预期。

内容的提问来源于stack exchange,提问作者Chr B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:57:16