使用Multer上传图片到Heroku时出现‘no such file or directory’错误求助
解决Heroku上Multer上传图片时的ENOENT错误
错误原因分析
- Heroku文件系统限制:Heroku的应用文件系统除
/tmp目录外均为只读状态,代码仓库中的目录部署后仅作为静态文件存在,Multer无法向应用根目录下的tmp目录写入内容。 - 目录路径不匹配:你代码中Multer的
destination使用了绝对路径/tmp/upload/images,这是系统根目录下的临时目录,而非代码仓库中的tmp目录,且该多级目录不会自动创建,导致Multer找不到目标路径报错。 - 静态文件配置错位:静态文件指向的是应用内的
tmp/upload/images,但Multer实际尝试写入系统根目录的/tmp,两者路径不一致,即使上传成功也无法访问文件。
修复步骤
1. 自动创建目标目录
Multer不会递归创建多级目录,需手动添加目录创建逻辑,使用Node.js内置fs模块实现:
const fs = require('fs'); const path = require('path'); const storage = multer.diskStorage({ destination: function (req, file, cb) { // 定义可写的目标目录,这里使用应用内的tmp目录(Heroku部署后需确保可写) const uploadDir = path.join(__dirname, 'tmp/upload/images'); // 递归创建目录,不存在则自动生成 fs.mkdirSync(uploadDir, { recursive: true }); cb(null, uploadDir); }, filename: (req, file, cb) => { return cb( null, `${file.fieldname}_${Date.now()}${path.extname(file.originalname)}` ); }, }); const upload = multer({ storage: storage });
2. 统一静态文件路径
调整静态文件中间件的路径,确保和Multer的目标目录一致,同时避免URL使用服务器内部路径:
app.use( '/uploads', // 前端访问用友好路径 express.static(path.join(__dirname, 'tmp/upload/images')) );
3. 注意临时存储局限性
Heroku的临时目录(包括应用内tmp和系统/tmp)都是临时存储,应用重启(部署、自动休眠)后文件会被清空。如果需要持久化存储图片,建议改用AWS S3、Cloudinary等云存储服务替代本地文件存储。
内容的提问来源于stack exchange,提问作者Wali Mirza
相关产品推荐
相关产品推荐

