简体   繁体   English

为什么我不能通过multer访问req.body?

[英]Why can't I access req.body with multer?

My app (using vue) allows users to upload files with some info about the data to my node backend. 我的应用程序(使用vue)允许用户将包含有关数据的一些信息的文件上传到我的节点后端。 When the user submits the form, this function is triggered: 用户提交表单时,将触发以下功能:

methods: {
      buttonOK () {
        const formData = new FormData()

        formData.append('name', this.detailFirm.name)
        formData.append('description', this.detailFirm.description)
        formData.append('version', this.detailFirm.version)
        formData.append('date', this.detailFirm.date)
        formData.append('file', this.file)

        for (var [key, value] of formData.entries()) {
          console.log(key, value)
        }

        let headers = {
          'Content-Type': 'multipart/form-data',
          'Accept': 'multipart/form-data'
        }

        this.$http.put('/firmware', formData, {headers: headers})
        this.visible = false
      }

The log statement shows everything that it ought to, and when this request is made, the network tab in the chrome dev tools shows the post data going through, and it has all the values it should: 日志语句显示了它应该执行的所有操作,并且在发出此请求时,chrome dev工具中的network标签显示了正在执行的发布数据,并且具有应具有的所有值:

name: test
description: test
version: 1
date: 0555-05-05
file: (binary)

My multer middleware looks like this: 我的multer中间件如下所示:

const multer = require('multer')
const mult = multer({
  dest: '/firmware'
})

module.exports = function (req, res, next) {
  /* --Convert multipart/form-data to useable format within express-- */
  if (req.path === '/firmware') {
    mult.single('file')
    console.log('MULTER MIDDLEWARE')
  }
  next()
}

The log statement there works, leading me to believe that multer is working. 那里的日志语句有效,使我相信multer在起作用。
I can't seem to access this information in back end though. 我似乎无法在后端访问此信息。 Here I have tried both file and formData as the file name in mult.single('') . 在这里,我尝试了fileformData作为mult.single('')的文件名。

Here is my controller function: 这是我的控制器功能:

let firmware = {
    name: req.body.name,
    version: req.body.version,
    description: req.body.description,
    date: req.body.date,
    file: req.body.file
  }
  firmwareRepo.create(firmware, (err, create) => {
                   .............

I've read some other questions, and have made a few adjustments, but I always get an empty object when I log req.body in the controller. 我已经阅读了其他一些问题,并进行了一些调整,但是当我在控制器中登录req.body时,总是得到一个空对象。 Please advise. 请指教。

EDIT: 编辑:

Firstly, I remember I had one problem on the frontend (React), by adding headers, which are not needed (somehow by adding formdata headers u **** up everything), here is the example: 首先,我记得我在前端(React)上遇到了一个问题,即添加了不需要的标头(以某种方式通过添加formdata标头将所有内容加起来),下面是示例:

data append stuff goes here 

const data = new FormData()

data.append('id', values.id)

...... ......

return async (dispatch) => {
                const respond = await fetch('/api/postdata', {
                method: 'post',
                headers: {
                   //SEE? THIS IS EMPTY
                },
                body: data
            })

            // send form to backend
            dispatch(dataSend())
        }
    }

Second issue could be on the backend. 第二个问题可能在后端。 The thing is, that you can't just simply access file info through the req.body. 事实是,您不能仅仅通过req.body访问文件信息。 You need to access it through the req.file 您需要通过req.file访问它

  .post('/api/post', (req, res, next)=> {
    const photo = {}
    const newData = {}

    uploadData(req, res, (err) => {
      if(err){
        console.log('error')
      }
      else {
        Object.assign(photo, {file: req.file})
        Object.assign(newData, {newData: req.body})

Then pass the photo to where you want to do something with it 然后将照片传递到您要对其进行处理的地方

    const addDataController = new AddDataController(req, res, next, newAdvertData, photo)
    addAdvertController.postAdvert()
  }
})

Basically what I did is I separated regular data with file, and passed them further to combine and conclude the form. 基本上,我所做的是我将常规数据与文件分开,然后将它们进一步传递以合并并得出表格。 Sorry if this won't help, you're very close anyways! 抱歉,如果这样做没有帮助,那么您还是很亲密!

https://github.com/expressjs/multer#diskstorage https://github.com/expressjs/multer#diskstorage

Note that req.body might not have been fully populated yet. 请注意,req.body可能尚未完全填充。 It depends on the order that the client transmits fields and files to the server. 这取决于客户端将字段和文件传输到服务器的顺序。

I don't know why this worked, but everything started functioning as it should when I stopped using multer as an imported middleware, like this: 我不知道为什么会这样,但是当我停止将multer用作导入的中间件时,一切都会开始正常运行,如下所示:

module.exports = function (req, res, next) {
  /* --Convert multipart/form-data to useable format within express-- */
  if (req.path === '/firmware') {
    mult.single('formData')
    console.log('MULTER MIDDLEWARE')
  }
  next()
}

and instead applied it directly to the route function, like this: 而是直接将其应用于route函数,如下所示:

router.put('/firmware', upload.single('formData'), firmware.create) // doesn't work as standalone middleware

If anyone knows why that would be the case, please let me know. 如果有人知道为什么会这样,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM