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

Heroku Flask应用临时文件访问与AWS S3存储问题排查

解决Heroku临时文件上传与AWS S3上传的问题

一、Heroku临时文件路径与端点错误修复

先来说你碰到的Heroku文件访问核心问题:

  1. Heroku的正确临时目录是/tmp,不是/app/tmp——Heroku每个运行的dyno都自带系统级的/tmp目录,它是默认存在的,不需要手动创建(当然手动创建也不影响,但完全没必要)。你之前在/app下找不到tmp,就是因为它本来就不在这个路径下。
  2. 你遇到的werkzeug.routing.BuildError,是因为redirect(url_for('app', ...))里的端点app根本不存在,Flask无法识别这个端点对应的路由。正确的做法是用send_from_directory直接返回临时目录里的文件。

修改后的代码如下:

# 修正上传目录配置
UPLOAD_FOLDER_FACES = '/tmp/'
app.config['UPLOAD_FOLDER_FACES'] = UPLOAD_FOLDER_FACES

# 导入需要的函数(如果没导入的话)
from flask import send_from_directory

# 修正display路由
@app.route('/displayfaces/<filename>')
def display_image_face(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER_FACES'], filename)

这样HTML里的{{ url_for('display_image_face', filename=filename) }}就能正确生成访问链接,图片也就可以正常加载了。

二、AWS S3上传的EOF错误修复

你碰到的AttributeError: fp is at EOF,是因为文件在上传到Heroku的/tmp目录后,文件指针已经移到了文件末尾,再传给S3的set_contents_from_file时,已经没有数据可以读取了。

修复方法很简单,在调用S3上传方法前,把文件指针重置到开头:

# 在调用set_contents_from_file之前添加这行
file.seek(0)
key.set_contents_from_file(file, headers=None, replace=True, cb=None, num_cb=10, policy=None, md5=None)

另外提一句,旧版的boto已经不再维护了,推荐升级到boto3,它的API更简洁稳定,用boto3实现上传的代码大概是这样:

import boto3

s3 = boto3.client('s3')
bucket_name = "facesappstorage"
# 重置文件指针
file.seek(0)
# 上传文件对象到S3
s3.upload_fileobj(file, bucket_name, filename)

额外提示

  • Heroku的/tmp是临时存储,只有当前运行的dyno能访问,一旦dyno重启(比如部署新代码、自动扩容或睡眠唤醒),里面的文件会被清空。如果需要持久化保存用户上传的文件,AWS S3这类云存储才是正确的选择。
  • 不要在Heroku的/app目录下创建自定义的临时文件夹,这个目录是你的代码部署目录,写入权限有限,而且不符合Heroku的临时存储规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 23:32:31