Search code examples
javascriptnode.jsmultersuperagent

req.files return undefined data while req.body is populated


Setting:

  • Node.JS(v8.9.4)
  • Express(v4.16.2)
  • Superagent v3.8.2(https://github.com/visionmedia/superagent) for POST from client
  • multer for file upload(v1.3.0)
  • React/Babel/Webpack
  • CentOS 7,Vultr VPS
  • File size limit is expaned to 50mb from nginx & multer
  • Deployed by private git(the version is consistent all across the platform)

Symptom:

When a mix up of stringified JSONdata and image are sent via http POST call, the server receives random amount of image via multer(multer.any()). The file is uploaded and exists in the server's public folder. req.body is also OK but somehow I cannot access the req.files. it returns undefined. From heroku and my desktop localhost, the app runs fine. The image is uploaded OK, accessing req.files data has no problem as well. Only the VPS/CentOS7 server has got the problem.

Client Side(React / Superagent / Babel / Webpack)

import request from 'superagent'

request.post('/modwimg')
.query({
  //some token and other info goes here
})
.accept('application/json')
.field('data',JSON.stringify(jsonData))
.attach('image',this.state.imagedata)
.attach('bannerimage',this.state.bannerimagedata)
.then((res)=>{
  console.log('upload finished')
  this.setState({goback:true})
})
.catch((err)=>{

})

Server Side

const bodyParser = require('body-parser')
const multer = require('multer')
const pubDir = path.join(__dirname, 'pub')
const storage = multer.diskStorage({
  destination: (req,file,cb)=>{
    cb(null,'pub/')
  },
  filename: (req,file,cb)=>{
    cb(null,Date.now() + file.originalname)
  }
})
const upload = multer({storage:storage})

//allowing public access, image goes to public dir
app.use('/pub', express.static(pubDir))

/* initialize bodyparser to build up RESTful app */
//file size limit expansion
app.use(bodyParser.urlencoded({limit:'50mb', extended:true}))
app.use(bodyParser.json({limit:'50mb'}))

app.post('/imageupload',upload.any(),(req,res,next)=>{
  //some token approval goes here
  console.log(req.files) // <----this returns undefined data, but image is still uploaded
  console.log(req.body) // <---- this is fine!!

  //putting data(JSON.parse(req.body)) to db
  db.any( //....
  )
  //then respond to client
  res.json({result:true})
})

Solution

  • Problem solved. I've changed extended option to extended:false from app.use(bodyParser.urlencoded({limit:'50mb', extended:true})), now it works like magic. I read from somewhere the extended option of bodyParser makes the rest of the http request data to some other format, so I've changed it and now it works.