Node.js TypeError: Cannot read property 'file' of undefined
Node.js TypeError: Cannot read property 'file' of undefined
我刚刚开始学习 node.js 并且很难使用 express 和 multer 进行简单的文件上传。
表格如下:
上传图片
在我的 configure.js
我有:
app.use(express.static(path.join(__dirname, 'public')));
app.use(multer({dest:'../public/upload/temp'}).single('file'));
和 image.js
控制器:
create: function(req, res) {
var saveImage = function() {
console.log(req.body);
var possible = 'abcdefghijklmnopqrstuvwxyz0123456789',
imgUrl = '';
for(var i=0; i < 6; i+=1) {
imgUrl += possible.charAt(Math.floor(Math.random() * possible.length));
}
var tempPath = req.files.file.path, //<line 55 error
ext = path.extname(req.files.file.name).toLowerCase(),
targetPath = path.resolve('./public/upload/' + imgUrl + ext);
if (ext === '.png' || ext === '.jpg' || ext === '.jpeg' || ext === '.gif') {
fs.rename(tempPath, targetPath, function(err) {
if (err) throw err;
res.redirect('/images/' + imgUrl);
});
} else {
fs.unlink(tempPath, function () {
if (err) throw err;
res.json(500, {error: 'Only image files are allowed.'});
});
}
};
saveImage();
},
然而,当我尝试上传图片时出现此错误:
TypeError: Cannot read property 'file' of undefined
at saveImage (/home/pc/node-dev/test-proj/controllers/image.js:55:37)
at module.exports.create (/home/pc/node-dev/test-proj/controllers/image.js:76:9)
at Layer.handle [as handle_request] (/home/pc/node-dev/test-proj/node_modules/express/lib/router/layer.js:95:5)
at next (/home/pc/node-dev/test-proj/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/home/pc/node-dev/test-proj/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/pc/node-dev/test-proj/node_modules/express/lib/router/layer.js:95:5)
at /home/pc/node-dev/test-proj/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/home/pc/node-dev/test-proj/node_modules/express/lib/router/index.js:330:12)
at next (/home/pc/node-dev/test-proj/node_modules/express/lib/router/index.js:271:10)
at urlencodedParser (/home/pc/node-dev/test-proj/node_modules/body-parser/lib/types/urlencoded.js:95:37)
当我记录 req
对象时,file
不存在:
{ title: 'myimage', description: 'something' }
实际上,该片段只是我在 this book 中读到的版本的略微修改,它使用的是过时的 express-3。所以基本上我只是用 multer
部分更新了它。
我想知道这里出了什么问题以及如何解决它。
您正在使用 upload.single
, which you should use req.file
not req.files
. To upload multiple files, use upload.array
。
请注意,在 req.file
之后您不需要另一个 .file
。如果您使用 upload.single
.
,则 req.file
是上传的文件
根据上面引用的相同 book,我能够在登录到控制台 req.files.file
并从控制台中的详细信息 path
中得出一个可行的解决方案存在于 file
对象中,它是 tempFilePath
而不是 path
,所以实际路径是 var tempPath = req.files.file.tempFilePath;
。以及完整代码
create: function(req, res){
var saveImage = function(){
var possible = 'abcdefghijklmnopqrstuvwxyz0123456789';
var imgUrl = '';
for(var i=0; i<6; i++){
imgUrl += possible.charAt(Math.floor(Math.random()*possible.length));
}
// if (!req.file) return console.log('Please upload a file')
console.log(req.files.file)
//
var tempPath = req.files.file.tempFilePath;
var ext = path.extname(req.files.file.name).toLowerCase();
var targetPath = path.resolve('./public/upload/' + imgUrl + ext);
if(ext === '.png' || ext === '.jpg' || ext === '.jpeg' || ext === '.gif'){
fs.rename(tempPath, targetPath, function(err){
if(err) throw err;
res.redirect('/images/' +imgUrl);
});
} else {
fs.unlink(tempPath, function(){
if(err) throw err;
res.json(500, {error: 'Only image files are allowed'});
})
}
}
saveImage();
}
The details to the console after logging the req.files.file
来自上面引用的同一本书,这是 2021 年,上面的所有代码都失败了,我为此奋斗了 4 天多,终于破解了。我将 multer 中间件移动到路由模块中以使其工作
将routes.js更新为
var express = require('express'),
path = require('path'),
router = express.Router(),
home = require('../controllers/home'),
image = require('../controllers/image');
const multer = require('multer')
const upload = multer({ dest: path.join(__dirname,
'public/upload/temp')});
module.exports = function(app) {
router.get('/', home.index);
router.get('/images/:image_id', image.index);
router.post('/images',upload.single('image'), image.create);
router.post('/images/:image_id/like', image.like);
router.post('/images/:image_id/comment', image.comment);
app.use(router);
};
将图像控制器中的创建功能更新为
create: function (req, res) {
var saveImage = function () {
var possible = "abcdefghijklmnopqrstuvwxyz0123456789",
imgUrl = "";
for (var i = 0; i < 6; i += 1) {
imgUrl += possible.charAt(Math.floor(Math.random() * possible.length));
}
var tempPath = req.file.path,
ext = path.extname(req.file.originalname).toLowerCase(),
targetPath = path.resolve("./public/upload/" + imgUrl + ext);
if (
ext === ".png" ||
ext === ".jpg" ||
ext === ".jpeg" ||
ext === ".gif"
) {
fs.rename(tempPath, targetPath, function (err) {
if (err) throw err;
res.redirect("/images/" + imgUrl);
});
} else {
fs.unlink(tempPath, function () {
if (err) throw err;
res.json(500, { error: "Only image files are allowed." });
});
}
};
saveImage();
}
从 configure.js 模块中注释掉或删除 multer 中间件
//app.use(multer({ dest: path.join(__dirname, 'public/upload/temp')}).single('image'));
确保您在 index.handlebars 中的表格与此相对应
<form method="post" action="/images" enctype="multipart/form-data" >
<div class="panel-body form-horizontal">
<div class="form-group col-md-12">
<label class="col-sm-2 control-label" for="file">Browse:</label>
<div class="col-md-10">
<input class="form-control" type="file" name="image" id="file">
</div>
</div>
<div class="form-group col-md-12">
<label class="col-md-2 control-label" for="title">Title:</label>
<div class="col-md-10">
<input class="form-control" type="text" name="title">
</div>
</div>
<div class="form-group col-md-12">
<label class="col-md-2 control-label" for="description">Description:</label>
<div class="col-md-10">
<textarea class="form-control" name="description" rows="2"></textarea>
</div>
</div>
<div class="form-group col-md-12">
<div class="col-md-12 text-right">
<button type="submit" id="login-btn" class="btn btn-success" type="button">
<i class="fa fa-cloud-upload ">
</i> Upload Image</button>
</div>
</div>
</div>
</form>
我刚刚开始学习 node.js 并且很难使用 express 和 multer 进行简单的文件上传。
表格如下:
上传图片在我的 configure.js
我有:
app.use(express.static(path.join(__dirname, 'public')));
app.use(multer({dest:'../public/upload/temp'}).single('file'));
和 image.js
控制器:
create: function(req, res) {
var saveImage = function() {
console.log(req.body);
var possible = 'abcdefghijklmnopqrstuvwxyz0123456789',
imgUrl = '';
for(var i=0; i < 6; i+=1) {
imgUrl += possible.charAt(Math.floor(Math.random() * possible.length));
}
var tempPath = req.files.file.path, //<line 55 error
ext = path.extname(req.files.file.name).toLowerCase(),
targetPath = path.resolve('./public/upload/' + imgUrl + ext);
if (ext === '.png' || ext === '.jpg' || ext === '.jpeg' || ext === '.gif') {
fs.rename(tempPath, targetPath, function(err) {
if (err) throw err;
res.redirect('/images/' + imgUrl);
});
} else {
fs.unlink(tempPath, function () {
if (err) throw err;
res.json(500, {error: 'Only image files are allowed.'});
});
}
};
saveImage();
},
然而,当我尝试上传图片时出现此错误:
TypeError: Cannot read property 'file' of undefined
at saveImage (/home/pc/node-dev/test-proj/controllers/image.js:55:37)
at module.exports.create (/home/pc/node-dev/test-proj/controllers/image.js:76:9)
at Layer.handle [as handle_request] (/home/pc/node-dev/test-proj/node_modules/express/lib/router/layer.js:95:5)
at next (/home/pc/node-dev/test-proj/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/home/pc/node-dev/test-proj/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/home/pc/node-dev/test-proj/node_modules/express/lib/router/layer.js:95:5)
at /home/pc/node-dev/test-proj/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/home/pc/node-dev/test-proj/node_modules/express/lib/router/index.js:330:12)
at next (/home/pc/node-dev/test-proj/node_modules/express/lib/router/index.js:271:10)
at urlencodedParser (/home/pc/node-dev/test-proj/node_modules/body-parser/lib/types/urlencoded.js:95:37)
当我记录 req
对象时,file
不存在:
{ title: 'myimage', description: 'something' }
实际上,该片段只是我在 this book 中读到的版本的略微修改,它使用的是过时的 express-3。所以基本上我只是用 multer
部分更新了它。
我想知道这里出了什么问题以及如何解决它。
您正在使用 upload.single
, which you should use req.file
not req.files
. To upload multiple files, use upload.array
。
请注意,在 req.file
之后您不需要另一个 .file
。如果您使用 upload.single
.
req.file
是上传的文件
根据上面引用的相同 book,我能够在登录到控制台 req.files.file
并从控制台中的详细信息 path
中得出一个可行的解决方案存在于 file
对象中,它是 tempFilePath
而不是 path
,所以实际路径是 var tempPath = req.files.file.tempFilePath;
。以及完整代码
create: function(req, res){
var saveImage = function(){
var possible = 'abcdefghijklmnopqrstuvwxyz0123456789';
var imgUrl = '';
for(var i=0; i<6; i++){
imgUrl += possible.charAt(Math.floor(Math.random()*possible.length));
}
// if (!req.file) return console.log('Please upload a file')
console.log(req.files.file)
//
var tempPath = req.files.file.tempFilePath;
var ext = path.extname(req.files.file.name).toLowerCase();
var targetPath = path.resolve('./public/upload/' + imgUrl + ext);
if(ext === '.png' || ext === '.jpg' || ext === '.jpeg' || ext === '.gif'){
fs.rename(tempPath, targetPath, function(err){
if(err) throw err;
res.redirect('/images/' +imgUrl);
});
} else {
fs.unlink(tempPath, function(){
if(err) throw err;
res.json(500, {error: 'Only image files are allowed'});
})
}
}
saveImage();
}
The details to the console after logging the req.files.file
来自上面引用的同一本书,这是 2021 年,上面的所有代码都失败了,我为此奋斗了 4 天多,终于破解了。我将 multer 中间件移动到路由模块中以使其工作
将routes.js更新为
var express = require('express'),
path = require('path'),
router = express.Router(),
home = require('../controllers/home'),
image = require('../controllers/image');
const multer = require('multer')
const upload = multer({ dest: path.join(__dirname,
'public/upload/temp')});
module.exports = function(app) {
router.get('/', home.index);
router.get('/images/:image_id', image.index);
router.post('/images',upload.single('image'), image.create);
router.post('/images/:image_id/like', image.like);
router.post('/images/:image_id/comment', image.comment);
app.use(router);
};
将图像控制器中的创建功能更新为
create: function (req, res) {
var saveImage = function () {
var possible = "abcdefghijklmnopqrstuvwxyz0123456789",
imgUrl = "";
for (var i = 0; i < 6; i += 1) {
imgUrl += possible.charAt(Math.floor(Math.random() * possible.length));
}
var tempPath = req.file.path,
ext = path.extname(req.file.originalname).toLowerCase(),
targetPath = path.resolve("./public/upload/" + imgUrl + ext);
if (
ext === ".png" ||
ext === ".jpg" ||
ext === ".jpeg" ||
ext === ".gif"
) {
fs.rename(tempPath, targetPath, function (err) {
if (err) throw err;
res.redirect("/images/" + imgUrl);
});
} else {
fs.unlink(tempPath, function () {
if (err) throw err;
res.json(500, { error: "Only image files are allowed." });
});
}
};
saveImage();
}
从 configure.js 模块中注释掉或删除 multer 中间件
//app.use(multer({ dest: path.join(__dirname, 'public/upload/temp')}).single('image'));
确保您在 index.handlebars 中的表格与此相对应
<form method="post" action="/images" enctype="multipart/form-data" >
<div class="panel-body form-horizontal">
<div class="form-group col-md-12">
<label class="col-sm-2 control-label" for="file">Browse:</label>
<div class="col-md-10">
<input class="form-control" type="file" name="image" id="file">
</div>
</div>
<div class="form-group col-md-12">
<label class="col-md-2 control-label" for="title">Title:</label>
<div class="col-md-10">
<input class="form-control" type="text" name="title">
</div>
</div>
<div class="form-group col-md-12">
<label class="col-md-2 control-label" for="description">Description:</label>
<div class="col-md-10">
<textarea class="form-control" name="description" rows="2"></textarea>
</div>
</div>
<div class="form-group col-md-12">
<div class="col-md-12 text-right">
<button type="submit" id="login-btn" class="btn btn-success" type="button">
<i class="fa fa-cloud-upload ">
</i> Upload Image</button>
</div>
</div>
</div>
</form>