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

在Heroku部署Express PERN应用时图片上传出现500错误如何解决

Heroku PERN应用图片上传返回500错误的解决方案

错误核心原因

  • Heroku的dyno实例采用临时文件系统,仅支持运行期间的临时写入,所有写入本地的文件会在dyno重启、重新部署、实例伸缩时被清空。且你当前代码没有提前判断上传目录是否存在,路径不存在时直接调用image.mv会直接触发错误返回500。
  • 代码中使用的../../build/uploads/img/为相对路径,Heroku Node.js运行环境的工作目录和本地开发环境不一致,相对路径解析后大概率指向不存在的目录,直接写入会抛出错误。

修复方案

生产环境标准方案

不要将用户上传的图片存储在Heroku本地,替换为第三方对象存储服务,上传逻辑改为将文件上传到对象存储后返回对应的公网访问地址,彻底规避Heroku临时文件系统的限制。

临时调试兼容方案

修改路径为绝对路径,服务启动时提前创建上传目录,修改后的代码如下:

const path = require('path');
const fs = require('fs');

// 拼接上传目录的绝对路径,__dirname为当前文件所在目录
const UPLOAD_DIR = path.resolve(__dirname, 'build', 'uploads', 'img');
// 启动时判断目录是否存在,不存在则递归创建
if (!fs.existsSync(UPLOAD_DIR)) {
  fs.mkdirSync(UPLOAD_DIR, { recursive: true });
}

Router.post('/upload-image', (req, res) => {
  try {
    // 验证是否上传了图片
    if (req.files === null) {
      return res.status(201).json({
        statusRequest: 'ok',
        imagePath: '/uploads/img/avatar.png'
      });
    }

    const image = req.files.file;
    const targetPath = path.join(UPLOAD_DIR, image.name);
    
    image.mv(targetPath, error => {
      if (error) {
        // 开发环境可打印错误排查,生产环境可移除
        console.error('上传失败:', error);
        return res.status(500).json({
          statusRequest: 'failed',
          errorInfo: 'Hubo un problema. Vuelve a intentarlo.'
        });
      }
      return res.status(201).json({
        statusRequest: 'ok',
        imagePath: `/uploads/img/${image.name}`
      });
    });
  } catch (error) {
    // 开发环境可打印错误排查,生产环境可移除
    console.error('接口异常:', error);
    return res.status(400).json({
      statusRequest: 'failed',
      errorInfo: 'Hubo un problema. Vuelve a intentarlo.'
    });
  }
});

注意:临时调试方案仅可用于测试,Heroku的dyno每24小时至少会自动重启一次,重启后所有上传的文件都会丢失,不可用于生产环境。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 22:06:07