Multer and Express/Node File Upload

matt.condit picture matt.condit · Oct 19, 2016 · Viewed 19.1k times · Source

req.files is producing null and now req.body is also blank. I've searched through all the answers here and can't find much. Unfortunately, the multer documentation was pretty lacking, so hopefully someone has gone through what I am right now and knows what is happening.

My router.js file is this:

var express = require('express');
var request = require('request');
var mid = require('../middleware');
var busboy = require('connect-busboy');
var fs = require('fs');
var multer = require('multer');
var upload = multer({dest: '../public/images/blog'});
var User = require('../data/models/user');
var router = express.Router();
...
...
...
...
/* POST saveblog router. */
router.post('/saveBlog', upload.any(),function(req, res, next) {
  console.log(req.body, 'Body'); 
  console.log(req.files, 'files');
  var title = req.body.titleInput;
  var body = req.body.bodyInput;
  request.post('http://' +req.headers.host + '/api/blog', {json: {body: body, title: title, userId: req.session.userId}},
  function(err, httpResponse, body) {
    if (err) {
      console.error('error posting blog');
    }
    console.log('Blog Post successfully uploaded');
  });
  return res.redirect('/blog');
}); 

module.exports = router;

So I'm not totally sure what's wrong with that, I originally had it as upload.single('image') but that didn't work either so who knows.

Here is my jade form to be submitted, if anyone can help but doesn't like jade I'm sure I can find a quick converter for it.

form(action='saveBlog', enctype='multipart/form-data', method='post')
  h1 New Blog Post 
  fieldset(data-role='')
    label(for='title') Title 
    input(id='titleInput', name='titleInput', type='text', value='', placeholder='Your Title', require='true').form-control
    label(for='image') Your Title Image
    input(id='image',name='image', type='file', accept='image/*')
    br
    label(for='body') Your Article (Box is resizable)
    textarea(id='mytextarea', name='bodyInput').form-control
    input(type='submit', value='Post your Article').btn.btn-primary

Answer

Dave picture Dave · Oct 19, 2016

I've been working on this today. One thing I noticed is that is you are using upload.single(), the data you're looking for will be in req.file not req.files.

I'm not sure if that's your issue though.

FYI, this slimmed down example works for me:

server.js

var express = require('express');
var app = express();

app.use(require('./routes'));

app.listen(8080);

routes.js

var express = require('express');
var multer = require('multer');
var upload = multer({ dest: '/tmp/' });
var router = express.Router();

/* POST saveblog router. */
router.post('/saveBlog', upload.any(), function(req, res, next) {
  console.log(req.body, 'Body');
  console.log(req.files, 'files');
  res.end();
});

module.exports = router;

I posted from Postman and got this output:

{ test: '1' } 'Body'
[ { fieldname: 'asdas',
    originalname: 'vcenter.png',
    encoding: '7bit',
    mimetype: 'image/png',
    destination: '/tmp/',
    filename: '92f425268efaa45cad31f67ec8f14c2d',
    path: '/tmp/92f425268efaa45cad31f67ec8f14c2d',
    size: 54834 } ] 'files'