Node.js TypeError: Cannot read property 'file' of undefined

时间:2016-02-03 04:29:28

标签: node.js express multer multifile-uploader

I'm just learning node.js and have difficulty to make a simple file upload using express and multer.

Here is the form:

Upload Image

In my configure.js I have:

app.use(express.static(path.join(__dirname, 'public')));
app.use(multer({dest:'../public/upload/temp'}).single('file'));

And the image.js controller:

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();
    },

However I get this error when I try to upload an image:

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)

And when I log the req object, file is not there:

{ title: 'myimage', description: 'something' }

Actually the snippet is just a slightly modified version what I read in this book, which is using outdated express-3. So basically I just updated it with the multer part.

I'm wondering what is wrong here and how to fix it.

2 个答案:

答案 0 :(得分:9)

您使用的是upload.single,您应使用req.file而不是req.files。要上传多个文件,请使用upload.array

请注意,.file之后您不需要另一个req.file。如果您使用req.file,则upload.single是上传的文件。

答案 1 :(得分:0)

从上面引用的相同的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