You need to enable JavaScript to run this app. React应用文件上传本地正常,nginx部署后提示目录不存在
优惠活动
大模型
产品
解决方案
定价
更多

React应用文件上传本地正常,nginx部署后提示目录不存在

React + Multer 生产环境文件上传报错问题

配置与现象

本地开发环境跑服务时,Multer的上传逻辑一切正常,文件可以顺利写到项目根目录的uploads文件夹里。当前的Multer配置如下:

const upload = multer({  // 配置Multer处理上传文件的落盘、重命名逻辑
  storage: multer.diskStorage({
    destination(req, file, cb) {
      cb(null, 'uploads/'); // 设置文件存储目录
    },
    filename(req, file, cb) {
      cb(null, `${new Date().getTime()}_${file.originalname}`); // 用时间戳+原文件名重命名,避免重名覆盖
    }
  }),
  limits: {
    fileSize: 1024 * 1024 * 5  // 单文件最大限制5MB
  },
  fileFilter: (req, file, cb) => { // 仅允许上传指定格式的图片
    if (file.mimetype == "image/png" 
        || file.mimetype == "image/jpg" 
        || file.mimetype == "image/jpeg" 
        || file.mimetype === 'image/gif' 
        || file.mimetype ==='image/jfif' ) {
      cb(null, true);
    } else {
      cb(null, false);
      return cb(new Error('Only .png, .jpg and .jpeg format allowed!'));
    }
  }
});

项目部署到Nginx托管的线上环境后,触发文件上传操作就直接报错,错误提示为:

Error: ENOENT: no such file or directory, open 'build/public/uploads/1619823055971_GettyImages-640318118-c83a508.jpg'

目前项目仅在根目录下放置了一个uploads文件夹,做完React生产构建后没有对这个目录做任何额外配置。

问题原因

这个报错和Nginx托管本身没有直接关系,是相对路径解析错位导致的:

  • 本地开发时,Node服务的启动目录就是项目根目录,配置里写的'uploads/'相对路径,会直接映射到根目录下的uploads文件夹,所以运行完全正常
  • 线上生产环境,Node服务是从build/public/目录下启动的,进程的工作目录发生了变化,同样的相对路径就会被自动解析成build/public/uploads/,但这个目录实际不存在,因此抛出“文件/目录不存在”的错误。

修复方法

直接按下面的步骤调整配置即可解决:

  • 不要用相对路径写上传目录,用Node内置的path模块拼接绝对路径定位目标目录,不管服务从哪个目录启动,路径都不会偏移:
    // 在入口文件顶部引入内置模块,不需要额外安装依赖
    const path = require('path');
    const fs = require('fs');
    
    // 修改Multer配置里的落盘路径逻辑
    storage: multer.diskStorage({
      destination(req, file, cb) {
        // 从当前入口文件位置,拼出项目根目录下uploads的绝对路径
        // (如果你的入口文件在build/public层级,需要往上跳两级才到项目根目录)
        const uploadPath = path.join(__dirname, '../../uploads/');
        // 检查目录是否存在,不存在就自动创建,避免下次启动还要手动建文件夹
        if (!fs.existsSync(uploadPath)) {
          fs.mkdirSync(uploadPath, { recursive: true });
        }
        cb(null, uploadPath);
      },
      // 原来的文件名重命名逻辑完全不用改
      filename(req, file, cb) {
        cb(null, `${new Date().getTime()}_${file.originalname}`);
      }
    })
    
  • 改完落盘路径后,如果需要直接通过公网链接访问上传的图片,要在Nginx配置里加一条静态资源映射规则,把请求路径里的/uploads指向你实际存文件的物理uploads目录,不然访问图片的时候会出现404。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 14:06:02