multer - req.file always undefined

33,685

Solution 1

Your enctype is slightly incorrect, it should be multipart/form-data instead of multipart/formdata.

Solution 2

In case of postman, try following:

  1. Close the postman tab for the API
  2. Open a new tab again
  3. Rebuild the API request and then send.

This may fix the problem. Every time you restart the server you need to do above steps for calling the API again. The reason being multer sends back some cookies called connect.sid to the client which it may require in further communication. Using old cookies will not upload the file.

Solution 3

Yes, your enctype is wrong and that is the only problem. Make sure that you correct your enctype otherwise you are likely to get undefined in req.file or req.files.

Solution 4

If you are using error handling as mentioned in the document, then req.file will be undefined.

An alternative way to use both error handling and to check if the file exists is to make use of express error handling:

index.js

const express = require("express");
const bodyParser = require("body-parser");
const upload = require("./upload");
const multer = require("multer");

const app = express();

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

app.get("/", function (req, res) {
  res.send("Hello World");
});

app.post("/upload_file", upload.single("file"), function (req, res) {
  if (!req.file) {
    throw Error("FILE_MISSING");
  } else {
    res.send("success");
  }
});

//Express Error Handling
app.use(function (err, req, res, next) {
  if (err instanceof multer.MulterError) {
    res.statusCode = 400;
    res.send(err.code);
  } else if (err) {
    if (err.message === "FILE_MISSING") {
      res.statusCode = 400;
      res.send("FILE_MISSING");
    } else {
      res.statusCode = 500;
      res.send("GENERIC_ERROR");
    }
  }
});

const server = app.listen(8081, function () {
  const port = server.address().port;

  console.log("App started at http://localhost:%s", port);
});

upload.js

const multer = require("multer");
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "./uploads");
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + "_" + file.originalname);
  },
});

const upload = multer({
  storage: storage,
  //   limits: { fileSize: 10 },
});

module.exports = upload;

Solution 5

I put MY (there are many I imagine and surely better) solution to help many people like me because I have searched during 1 entire day ;-(


//JS file on node side

var express = require('express');
var fileUpload = require('express-fileupload');
var fs = require("fs");
var app = express();
console.log('étape 0');
app.use(express.static('mesStatic'));
app.use(fileUpload());
console.log('étape 1');
app.get('/indexFileUpload.htm', function (req, res) {
   res.sendFile( __dirname + "/" + "indexFileUpload.htm" );
})
console.log('étape 2');
app.post('/file_upload', function (req, res) {

   console.log('étape 3');
   console.log('req.files:' , req.files);
   if (!req.files) {
       res.send('No files to upload.');
       return;
   }

   console.log('req.files.file.data:' , req.files.file.data);
   var bufDataFile = new Buffer(req.files.file.data, "utf-8");
   console.log('étape 3.1');
   console.log('__dirname : ' + __dirname);
   fs.writeFile(__dirname + '/file_upload/output.txt', bufDataFile,  function(err) {
      if (err) {
         return console.error(err);
      }
      else {
         console.log("Data written successfully !");
      }      
      console.log('étape 4');
      res.end('Fin OK !!!');  
   })
})
var server = app.listen(8081, function () {
   var host = server.address().address
   var port = server.address().port

   console.log("Example app listening at http://%s:%s", host, port);
})
Share:
33,685
mlamp
Author by

mlamp

Updated on July 21, 2021

Comments

  • mlamp
    mlamp almost 3 years

    I've looked at a lot of answer for this same question, but I haven't found a working solution yet. I am trying to make a web app that you can upload files to using express and multer, and I am having a problem that no files are being uploaded and req.file is always undefined.

    My code below

    'use strict';
    
    var express = require('express');
    var path    = require('path');
    var multer  = require('multer')
    var upload  = multer({ dest: 'uploads/' })
    
    var app = express();
    require('dotenv').load();
    
    app.use(express.static(path.join(__dirname, 'main')));
    
    app.post('/upload', upload.single('upl'), function (req, res, next) {
      // req.file is the `avatar` file
      // req.body will hold the text fields, if there were any
      console.log(req.file);
      res.status(204).end();
    })
    
    var port = process.env.PORT || 8080;
    app.listen(port,  function () {
        console.log('Node.js listening on port ' + port + '...');
    });
    

    The form

        <form class="uploadForm" action="/upload" method="post" enctype="multipart/formdata">
            <label class="control-label">Select File</label>
            <input name="upl" id="input-1" type="file" class="file">
            <input type="submit" value="submit" />
        </form>
    

    Help very much appreciated, this is driving me crazy.