部署在Heroku上的应用下载功能失效、本地运行正常,该如何排查?
问题原因
- Heroku采用临时文件系统:dyno运行过程中写入的所有文件,都会在dyno重启、回收(每24小时至少回收一次)时被清空,且默认未配置静态资源映射的目录下的文件,前端无法直接通过URL访问。你代码中写入的用户主目录
os.path.expanduser('~')不属于可公开访问的静态目录,就算文件写入成功,前端也无法触发下载。 - 目录写入权限问题:Heroku运行应用的用户没有自定义用户主目录的写入权限,会导致
os.mkdir(down_path)或者后续写入文件操作失败,本地环境因为使用的是管理员/普通用户权限,对个人主目录有读写权限所以运行正常。 - 缺少正确的下载响应逻辑:你当前代码仅完成了文件写入服务器本地的逻辑,没有构造符合HTTP规范的下载响应返回给前端,本地运行时可能因为前后端都在同一个设备,能直接访问本地文件路径所以正常,部署到远端后该逻辑完全失效。
解决方案
- 替换写入目录为Heroku官方允许的临时目录
/tmp,该目录是Heroku唯一开放运行时读写权限的目录,修改路径代码:
import os down_path = os.path.join('/tmp', 'TempDownload') if not os.path.exists(down_path): os.mkdir(down_path) filename = os.path.join(down_path, localnow+'ssc.tif') geemap.ee_export_image(ssc_intial, filename=filename, scale=110, region=roi, file_per_band=False)
- 补充下载响应逻辑:根据你使用的Web框架,构造正确的文件下载响应,设置对应响应头,将生成的文件返回给前端。以Flask框架为例:
from flask import send_file # 写完文件后添加以下返回逻辑 return send_file( filename, as_attachment=True, download_name=f"{localnow}ssc.tif", mimetype='image/tiff' )
- 大文件场景优化:如果导出的tif文件体积较大,或者需要长期留存下载链接,建议不要存储在Heroku本地
/tmp目录,而是导出到第三方对象存储服务,生成公开下载链接后返回给前端触发下载,避免临时文件被清理导致下载失败。
内容的提问来源于stack exchange,提问作者bluesky su
相关产品推荐
相关产品推荐

