简体   繁体   English

req.file 未定义多个文件上传

[英]req.file is undefined for multiple file uploads

I've read through all the possible answers here but I'm not sure anymore what the problem could be because none of them works.我已经阅读了所有可能的答案,但我不确定问题可能出在哪里,因为它们都不起作用。 I have one form that uploads a single image and it works as expected but on a different form where I try and upload multiple files and have form inputs, the req.file is always undefined and the image data ends up in the req.body.我有一个上传单个图像的表单,它按预期工作,但是在我尝试上传多个文件并有表单输入的不同表单上,req.file 始终未定义,图像数据最终在 req.body 中。 So somewhere I think maybe there is an issue where multer is not getting the file data...?所以在某个地方我认为可能存在 multer 没有获取文件数据的问题......?

I read in a couple of places that body-parser is possibly not playing well with multer but I unfortunately need them both.我在几个地方读到 body-parser 可能不能很好地与 multer 配合使用,但不幸的是我需要它们。

route路线

const destination = './public/uploads/posts';
const storage = multer.diskStorage({
  destination: destination,
  filename: (req, file, cb) => {
    cb(null, file.originalname);
  },
});
const upload = multer({storage}).array('images');

router.post('/posts', (req, res) => {

  upload(req, res, (err) => {
    if(err) {
      console.log('errors', err)
      res.json({success: false, error: err})
    } else {
      if(req.files === undefined) {
        console.log('error: Images returned undefined');
      } else {
        const { title, description, url, auth_name, auth_id } = req.body;

        if(!title || !description) {
          return res.json({
            success: false,
            error: 'All fields required',
            message: 'Title and description fields are required'
          });
        }

        // path we store in the db
        let imageLocation = [];
        const post = new Post();

        for (const file of req.files) {
          imageLocation.concat('/uploads/posts/' + file.filename)
        }

        post.title = title;
        post.description = description;
        post.url = url;
        post.author_name = auth_name;
        post.author = auth_id;
        post.images = imageLocation;
        post.save((err, post) => {
          if(err) {
            return res.json({ success: false, error: err, message: 'post failed' });
          } else {
            return res.json({ success: true, message: "added new post", post: post });
          }
        });
      }
    }
  });
});

post in react component在反应组件中发布

My images are set in state which I get from the DropZone package (I tested without DropZone as well with same results. I made sure the the input name is "images"我的图像设置在 state 中,我从 DropZone package 获得(我在没有 DropZone 的情况下也进行了测试,结果相同。我确保输入名称是“图像”

submitNewPost = () => {
    const { title, description, url, images } = this.state;
    const auth_id = this.props.author_id;
    const auth_name = this.props.author_name;

    const formdata = new FormData();
    formdata.append('title', title);
    formdata.append('description', description);
    formdata.append('url', url);
    formdata.append('author_name', auth_name);
    formdata.append('author', auth_id);
    formdata.append('images', images);

    fetch('/api/posts', {
      method: 'POST',
      body: formdata
    }).then(res => res.json())
      .then((res) => {
        if (!res.success) {
          this.setState({ message: res.message });
        } else {
          this.setState({ 
              title: '', 
              description: '', 
              url: '', 
              images: '', 
              message: res.message 
          });
          socket.emit('newPost', res.post);
        }
      });
  }

UPDATE更新

With some help on this thread I managed to upload the images using my existing route and postman.在此线程上的一些帮助下,我设法使用我现有的路线和 postman 上传了图像。 When I test the route using my form, I still get an empty req.file and no uploads.当我使用我的表单测试路线时,我仍然得到一个空的 req.file 并且没有上传。

I added express-multipart-file-parser to my setup and I figure that is what brought me one step closer to fixing this.我在我的设置中添加了 express-multipart-file-parser,我认为这让我离解决这个问题更近了一步。

Server服务器

This is what I added to my server.js这是我添加到 server.js 中的内容

 import { fileParser } from 'express-multipart-file-parser';
 app.use(fileParser({
  rawBodyOptions: {
      limit: '15mb',  //file size limit
  },
  busboyOptions: {
      limits: {
         fields: 20   //Number text fields allowed 
      }
  },
 }));

To properly populate req.files you need to use formdata.append like this: 要正确填充req.files您需要使用formdata.append如下所示:

images.forEach(image => {
  formdata.append('images', image);
})

You are missing to pass value with array. 您缺少通过数组传递值的方法。

router.post('posts', upload.array('image', 10), function (req, res, next) {

})

thanks for all the help. 感谢所有的帮助。 I managed to fix it. 我设法解决了。 Turns out I was concatenating the FileList object to an array in my state so the structure was all wrong and at the server it just failed. 原来,我正在将FileList对象连接到处于我的状态的数组,因此结构都错了,而在服务器上它只是失败了。 My images upload perfectly now. 我的图像现在完美上传。

If I posted that part of my react component, I'm sure any of you would have picked up on that in a second, sorry. 如果我发布了我的react组件的那一部分,我敢肯定,你们中的任何人都会在一秒钟内对此有所了解,抱歉。 Did not occur to me that the problem was further up in my component. 我没有想到问题在我的组件中进一步蔓延。

THE PROBLEM 问题

onFileLoad = (e) => {
  this.setState({
    images: this.state.images.concat(e.target.files)
  });
}

THE FIX 修复

onFileLoad = (e) => {
  this.setState({
   images: e.target.files
  });
}

submitMediaPOst = () => {
  const imageArr = Array.from(images);
  imageArr.forEach(image => {
    formdata.append('images', image);
  });
...

for this issue not getting req.file in controller after upload middlewar, while testing in postman select multiple file in single property对于此问题,在上传中间件后,在 controller 中没有获取 req.file,而在 postman select 中测试单个属性中的多个文件在此处输入图像描述 and ofcourse in front end append the files in a loop当然在前端 append 循环中的文件

   doc.forEach(file=> {
      formdata.append('file', file);
    }

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

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