Express 3.4.8照片上传问题 - 如何在不使用bodyParser()的情况下解决?

时间:2014-04-14 14:53:20

标签: node.js file-upload express mongoose middleware

我在Gist的代码: https://gist.github.com/yhagio/10654836

我是Express的新手,试过这本书的例子" Node.js in Action - Chapter.9"(上传照片)。 作者使用Express版本" 3.4.0"但是我用了#34; 3.4.8"我遇到了这个问题,

尝试上传图片时出现错误消息:

500 TypeError: Cannot read property 'photo' of undefined

路由/ photos.js

...
exports.submit = function (dir) {
  return function (req, res, next) {
    var img = req.files.photo.image; // ---- This 'photo' part is undefined
    var name = req.body.photo.name || img.name;
    var path = join(dir, img.name);

    fs.rename(img.path, path, function (err) {
      if (err) { return next(err); };

      Photo.create({
          name:name,
          path:req.name
        }, function (err) {
        if (err) { return next(err); };
        res.redirect('/');
      });
    });
  };
}; 

但我发现在我的app.js中(自3.4.8起不再使用bodyParser())

app.js (在我的代码Express 3.4.8中)

...
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.json());       // Instead of bodyParser()
app.use(express.urlencoded()); // Instead of bodyParser()
...

但是作者的代码中有bodyParser()。

app.js (作者使用Express 3.4.0

...
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser()); // This is no longer used in latest version

所以,我想知道我是否可以使用multer(http://expressjs-book.com/forums/topic/replacement-for-bodyparser-connect-multipart/)解决这个问题:

app.use(express.json());       
app.use(express.urlencoded());
app.use(multer({ dest: './public/photos' })); // I tried this

这没有解决。请帮我。谢谢。

更新:解决方案我想出了

此代码有效(routes / photos.js)

exports.submit = function (dir) {
  return function(req, res, next){
    var form = new multiparty.Form();
    form.parse(req, function(err, fields, files){
      var img = files.image[0];
      var name = fields.name || img.originalFilename;
      var path = join(dir, img.originalFilename);
      fs.rename(img.path, path, function(err){
        if(err){return next(err); };
        Photo.create({
          name: name,
          path: img.originalFilename
        }, function(err){
          if(err){return next(err); };
          res.redirect('/');
        });
      });
    });
  };
}; 

2 个答案:

答案 0 :(得分:4)

您试过node-multiparty了吗?以下是自述文件中的示例用法:

var multiparty = require('multiparty')
  , http = require('http')
  , util = require('util')

http.createServer(function(req, res) {
  if (req.url === '/upload' && req.method === 'POST') {
    // parse a file upload
    var form = new multiparty.Form();

    form.parse(req, function(err, fields, files) {
      res.writeHead(200, {'content-type': 'text/plain'});
      res.write('received upload:\n\n');
      res.end(util.inspect({fields: fields, files: files}));
    });

    return;
  }

  // show a file upload form
  res.writeHead(200, {'content-type': 'text/html'});
  res.end(
    '<form action="/upload" enctype="multipart/form-data" method="post">'+
    '<input type="text" name="title"><br>'+
    '<input type="file" name="upload" multiple="multiple"><br>'+
    '<input type="submit" value="Upload">'+
    '</form>'
  );
}).listen(8080);

作者(Andrew Kelley)recommends避免使用bodyParser,所以你应该避免使用它,但是多方似乎为我解决了类似的问题。

答案 1 :(得分:1)

它不再有效的原因是因为Express中不再包含node-formidable库。如果您想继续使用强大的,请按照这些说明操作。

在Express 4.x中使用body-parser的正确方法是:

var express = require('express'),
    bodyParser = require('body-parser'),
    app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

访问文件:

var formidable = require('formidable'),
    form = new formidable.IncomingForm();

exports.submit = function (dir) {
    return function (req, res, next) {
        form.parse(req, function(err, fields, files) {
            // The files object here is what you expected from req.files
        });
    });
});

注意:如果您尝试使用多个,请设置:

form.multiples = true;