Node.js图片上传报错ENOENT:找不到文件或目录,求问题排查
Node.js图片上传报错ENOENT的解决方法
按照教程实现Node.js文件上传功能,但图片上传失败,报错如下:
Error: ENOENT: no such file or directory, open 'C:\Users\User\Downloads\fileuplloaddownload-master\public\uploads\pexels-luiisrtz-1693399.jpg'
怀疑是代码版本过时,但检查代码未发现明显错误,以下是相关代码及依赖版本:
提供的代码
app.js
var express = require('express'); var mongoose = require('mongoose'); var bodyParser = require('body-parser'); var multer = require('multer'); var path = require('path'); var picSchema= new mongoose.Schema({ picpath:String }) var picModel = mongoose.model('picsdemo',picSchema); var storage = multer.diskStorage({ destination:function(req,file,cb){ cb(null,'./public/uploads') }, filename:function(req,file,cb){ cb(null,file.originalname) } }) var upload = multer({storage:storage}) var app = express(); mongoose.connect('mongodb://localhost:27017/pics',{useNewUrlParser:true}) .then(()=>console.log('connected')).catch(err=>console.log('error ocured',err)); app.set('views',path.resolve(__dirname,'views')); app.set('view engine','ejs'); var pathh = path.resolve(__dirname,'public'); app.use(express.static(pathh)); app.use(bodyParser.urlencoded({extended:false})); app.get('/',(req,res)=>{ picModel.find((err,data)=>{ if(err){ console.log(err) } else if(data.length>0){ res.render('home',{data:data}) } else{ res.render('home',{data:{}}) } }) }) app.post('/',upload.single('pic'),(req,res)=>{ var x = 'uploads/'+req.file.originalname; var temp = new picModel({ picpath:x }) temp.save((err,data)=>{ if(err){ console.log(err) } res.redirect('/') }) }) app.get('/download/:id',(req,res)=>{ picModel.find({_id:req.params.id},(err,data)=>{ if(err){ console.log(err) } else{ var x= __dirname+'/public/'+data[0].picpath; res.download(x) } }) }) var port = process.env.PORT || 3000 ; app.listen(port,()=>console.log('server running at port'+port))
home.ejs
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <form action="/" method="POST" enctype="multipart/form-data"> <input type="file" name="pic" id="pic"><br> <input type="submit" value="upload file"> </form><br><br><br><br> <% if(data.length > 0) {%> <table> <thead> <tr> <td> images </td> <td> download </td> </tr> </thead> <tbody> <% for(var i=0; i< data.length; i++) {%> <tr> <td> <img src="<%= data[i].picpath%>" alt="images" style="width:100px; height:100px;"> </td> <td> <form action="/download/<%= data[i]._id%>"> <input type="submit" value="download"> </form> </td> </tr> <% } %> </tbody> </table> <% } %> </body> </html>
使用的依赖版本
"body-parser": "^1.19.0",
"ejs": "^2.7.1",
"express": "^4.17.1",
"mongoose": "^5.7.7",
"multer": "^1.4.2"
解决方法
1. 确保目标目录存在
multer不会自动创建public/uploads目录,这是报错的核心原因。你可以手动在项目根目录创建public/uploads文件夹,或者在代码中用fs模块自动创建:
在app.js顶部引入fs模块:
var fs = require('fs');
然后在multer storage配置前添加目录创建逻辑:
var uploadDir = path.resolve(__dirname, './public/uploads'); if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir, { recursive: true }); }
2. 修正multer的路径配置
使用相对路径可能因当前工作目录变化导致问题,建议改用绝对路径:
var storage = multer.diskStorage({ destination:function(req,file,cb){ cb(null, path.resolve(__dirname, './public/uploads')) }, filename:function(req,file,cb){ cb(null,file.originalname) } })
3. 代码优化建议
- 完善错误处理:在
picModel.find和temp.save的回调中,除打印错误外,需给客户端返回错误响应,比如res.status(500).send('服务器错误') - 用findOne替代find:下载接口中根据_id查询单个文件,用
picModel.findOne更合适,无需取数组第0项:
app.get('/download/:id',(req,res)=>{ picModel.findOne({_id:req.params.id},(err,data)=>{ if(err){ console.log(err); return res.status(500).send('查询失败'); } if(!data){ return res.status(404).send('文件不存在'); } var x= path.resolve(__dirname, 'public', data.picpath); res.download(x) }) })
- 移除body-parser依赖:Express 4.16+已内置body-parser功能,可替换为:
app.use(express.urlencoded({extended:false}));
之后可删除body-parser依赖包。
4. 版本兼容性说明
你使用的依赖版本不存在兼容性问题,multer@1.4.2与Express@4.17.1配合正常,报错与版本无关,核心是目录不存在和路径配置问题。
内容的提问来源于stack exchange,提问作者pia punya Munirah
相关产品推荐
相关产品推荐

