'multer express not passing form-data into body

I am trying to make an internal API proxy for when we need to hit external API's that pass creds like API keys "in the clear" so we can hide them in environment variables on our internal API server.

The issue I am running into is with form-data submissions. I am using body-parser which is letting me read json fine, but i am having trouble passing in form-data submissions with a file.

I have tried to use multer to parse the response for me, but its not working with my postman payload (which is think is a unique case as i CANNOT pass the Content-Type headers or it messes up the call).

Here is a code snippet of how i have multer setup, when i hit one of my end points with form-data from postman the req.body and req.files always show up empty. I can pass json to these endpoints no problem so i am pretty sure this is an issue with multer since body-parser doesnt support multipart/form-data.

server.js

const express = require('express');
const app = express();
const multer  = require('multer')
app.use(multer().array());
app.use('/apiProxy', apiLimiter, require('./routes/api/apiProxy')); 
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));

/routes/api/apiProxy

const url = require('url')
const express = require('express')
const router = express.Router()
const needle = require('needle')
const apicache = require('apicache')


router.post('/externalVendor/createAttachment', async (req, res, next) => {
    try {
       
              // Log the request to the public API
      if (process.env.NODE_ENV !== 'production') {

        console.log("headers")
        console.log(req.headers)
        console.log("REQ BODY")
        console.log(req);
        console.log("REQ FILES")
        console.log(req.files)

      }

      const headers = (req.headers,authHeader );
        console.log(headers)
      const params = url.parse(req.url, true).query

      const options = {
        follow: 5,
        headers: headers
    };
      const apiRes = await needle('post', `${process.env.API_URL}/${params.docID}/attachments/`, req.body, options)
      const data = apiRes.body
  

  
      res.status(200).json(data)
    } catch (error) {
console.log("hi")

        console.log("headers")
        console.log(req.headers)
        console.log("REQ BODY")
        console.log(req.body);
      next(error)
    }
  })


module.exports = router


Post man payload example

var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
data.append('file', fs.createReadStream('/home/lenovo/Downloads/zoom background final.jpg'));
data.append('fuck', 'multipart forms');

var config = {
  method: 'post',
  url: 'localhost:3000/apiProxy/externalVendor/createAttachment/?docID=bPhg5s4DqbadS6GrLqirHD',
  headers: {  
    ...data.getHeaders()
  },
  data : data
};

axios(config)
.then(function (response) {
  console.log(JSON.stringify(response.data));
})
.catch(function (error) {
  console.log(error);
});

Reponse if i include the header Content-Type: multipart/form-data (if i dont include the header the endpoint replies successfully but with an error because the body is missing with the payload)

{
    "success": false,
    "error": "content-type missing boundary",
    "stack": "BadRequestError: content-type missing boundary\n    at Form.parse (/home/lenovo/git/api-core/node_modules/multiparty/index.js:183:21)\n    at multipart (/home/lenovo/git/api-core/node_modules/connect-multiparty/index.js:117:10)\n    at /home/lenovo/git/api-core/node_modules/express-form-data/index.js:74:31\n    at Layer.handle [as handle_request] (/home/lenovo/git/api-core/node_modules/express/lib/router/layer.js:95:5)\n    at trim_prefix (/home/lenovo/git/api-core/node_modules/express/lib/router/index.js:323:13)\n    at /home/lenovo/git/api-core/node_modules/express/lib/router/index.js:284:7\n    at Function.process_params (/home/lenovo/git/api-core/node_modules/express/lib/router/index.js:341:12)\n    at next (/home/lenovo/git/api-core/node_modules/express/lib/router/index.js:275:10)\n    at expressInit (/home/lenovo/git/api-core/node_modules/express/lib/middleware/init.js:40:5)\n    at Layer.handle [as handle_request] (/home/lenovo/git/api-core/node_modules/express/lib/router/layer.js:95:5)"
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source