question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Empty `body` and `files` request properties

See original GitHub issue

I feel like I must be doing something extremely silly here, but can replicate my problem in a really simple app following your examples. Perhaps there is something really weird with my node setup.

Platform: OSX El Capitan Node Version: v5.12.0 (I’ve also nvm-ed and tried with v6.7.0, same outcome)

Expected Result: POST multipart/form-data requests with the multer middleware should add body and files properties to the request object with the data.

What happens for me: Empty req.body or req.files data from POST requests. Multer throws no errors and returns empty object and array for them respectively.

I’ve made a simple repo that shows my setup: https://github.com/jamsinclair/multer-test

My server js is literally: (I’ve tried using different api methods, .array(), .single('name'), .none() etc, still the same outcome)

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

var upload = multer({ dest: './uploads' })

app.post('/upload', upload.any(), function (req, res, next) {
  console.log('body data:', req.body);
  console.log('files data:', req.files);
  res.sendStatus(200);
});

app.listen(9000, function () {
  console.log('Listening on port 9000');
});

Example payload being sent via Postman:

POST /upload HTTP/1.1
Host: localhost:9000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: 40d74092-2b02-12c4-b213-6ecd515ff61f

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="foo"

bar
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="name"

multer
------WebKitFormBoundary7MA4YWxkTrZu0gW--

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:16

github_iconTop GitHub Comments

5reactions
serhiipalashcommented, Jul 29, 2018

I ended up using solution from @wcandillon article https://medium.com/@wcandillon/uploading-images-to-firebase-with-expo-a913c9f8e98d

const cors = require('cors')
const bodyParser = require('body-parser')
const Busboy = require('busboy')
const getRawBody = require('raw-body')
const contentType = require('content-type')

app.post(
  '/post-tweet',
  [
    // middlewares

    cors({ origin: true }),

    bodyParser.json(),

    bodyParser.urlencoded({
      extended: true,
    }),

    (req, res, next) => {
      if (
        req.rawBody === undefined &&
        req.method === 'POST' &&
        req.headers['content-type'].startsWith('multipart/form-data')
      ) {
        getRawBody(
          req,
          {
            length: req.headers['content-length'],
            limit: '10mb',
            encoding: contentType.parse(req).parameters.charset,
          },
          function(err, string) {
            if (err) return next(err)
            req.rawBody = string
            next()
          }
        )
      } else {
        next()
      }
    },

    (req, res, next) => {
      if (
        req.method === 'POST' &&
        req.headers['content-type'].startsWith('multipart/form-data')
      ) {
        const busboy = new Busboy({
          headers: req.headers,
        })

        var fileBuffer = new Buffer('')

        busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
          file.on('data', data => {
            fileBuffer = Buffer.concat([fileBuffer, data])
          })

          file.on('end', () => {
            const file_object = {
              fieldname,
              originalname: filename,
              encoding,
              mimetype,
              buffer: fileBuffer,
            }

            req.file = file_object
          })
        })

        req.data = {}

        busboy.on('field', function(
          fieldname,
          val
          // fieldnameTruncated
          // valTruncated
          // encoding
          // mimetype
        ) {
          req.data[fieldname] = val
        })

        busboy.on('finish', function() {
          console.log('Done parsing form!')

          next()
        })

        busboy.end(req.rawBody)
      } else {
        next()
      }
    },
  ],
  function(req, res, next) {
    // request handler
    const file = req.file

    console.log(file)
  }
)

It will be much simpler to just use one middleware, but it doesn’t work in Firebase cloud 😦

var multer = require('multer');
var upload = multer({ dest: './uploads' })

app.post(
  '/post-tweet',
  upload.single('photo'),
  function(req, res, next) {
    // request handler
    const file = req.file

    console.log(file)
  }
)
4reactions
jamsinclaircommented, Oct 25, 2016

After much digging around finally stumbled upon my answers here http://stackoverflow.com/a/10765244/5179940

  • The body data for the multipart/form-data requests must end with CLRF(\r\n) line endings.

  • The body data boundaries have an extra -- prepended For example, The header with boundary defined:

    Content-Type: multipart/form-data; boundary=--123456
    

    Note how the body data boundaries have an extra -- prepended Body Data:

    ----123456
    Content-Disposition: form-data; name="foo"
    
    Bar
    ----123456--
    

Issue resolved for myself.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Request body is empty when submitting data using "form data"
the request body when using form data is an empty object. Why is this happening? Here's my update code: exports.updateProgram = catchAsync(async ...
Read more >
Request Body - FastAPI
A request body is data sent by the client to your API. A response body is the data your API sends to the...
Read more >
API Reference - Express 4.x
A new body object containing the parsed data is populated on the request object after the middleware (i.e. req.body ), or an empty...
Read more >
Requests - Starlette
If you don't need to access the request body you can instantiate a request without providing an argument to receive . Method. The...
Read more >
Returning stubbed HTTP responses to specific requests
When running the standalone JAR, files placed under the __files directory will be served up as if from under the docroot, except if...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found