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
相关产品推荐
相关产品推荐

