javascriptnode.jsexpressfile-upload

Standard upload form on NodeJS has an empty file field


I want to upload a file to a NodeJS server. Following File uploading with Express 4.0: req.files undefined , I try this code in mre.js:

'use strict';

const path = require('path');
const express = require('express');
const app = express();

// Set up the view engine
app.set('view engine', 'pug');
app.set('views', path.join(__dirname, 'views'));


const UPLOAD = "/upload";

app.get(UPLOAD, async (req, res) => {
  
  return res.render("upload");
});


const fileUpload = require('express-fileupload');

app.post(UPLOAD, fileUpload(), async (req, res) => {
  let keys = Object.keys(req.files);
  fs.readFile(req.files[keys[0]].path, (err, e) => {
    if(err) console.log(err);
    fs.writeFile(keys[0], e, (err) => {
      console.log(err)
    })
  })

  req.flash("success", "File uploaded");
  return res.redirect(UPLOAD);
});



const http = require('http');
const httpServer = http.createServer(app);

let server = httpServer.listen(8080, () => {
  console.log("\n# HTTP server started");
});

and the view is:

doctype html
html

  body
    form(method='POST')
    
      input(type='file', id="file", name="filename", accept=".xls,.xlsx,.txt")
      input(type="submit", name="submit", value="Upload")

I launch with node mre.js, I see the form at http://localhost:8080/upload, but when I upload a file, I get this error:

mre.js:24
  let keys = Object.keys(req.files);
TypeError: Cannot convert undefined or null to object

I tried several variations to no avail, for example I log the full request with console.log(req), and the filename I uploaded does not appear. But it seems to work on multiple answers of that thread, so I think there's something obvious I am overlooking. The NodeJS version is 22.2.0.

How can I get the file uploaded to a NodeJS server?


Solution

  • The problem is with the request: your form is sending URL-encoded request, so the file content is not included, so the req.files is undefined, breaking your code.

    You need to send multipart request. So, add enctype="multipart/form-data" attribute to the form:

    form(method='POST', enctype="multipart/form-data")