Search code examples
expressfile-uploadupload

upload file to express multi can't receive file in the request


I am working on vue element-plus upload component to upload the image to the express server.

Here is the client side

  <el-upload
    action="/"
    :auto-upload="false"
    :show-file-list="false"
    :on-change="uploadFile"
    >

const uploadFile = async (file) => {
      const formData = new FormData();
      formData.append("file", file);
      axios.post( `http://localhost:3000/api/v1/upload`, formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }   ).then(resp => {
        var rdata = resp.data

        console.log(rdata);
      }).catch(error => {
        console.log(error);
      });
}

here is the server side

import multer from "multer";
const upload = multer({
  dest: 'uploads'
})
productRoute.post(
  "/api/v1/upload",
  upload.single("file"),
  (req, res) => {
    console.log('upload 111', req.file);
    console.log('upload 222', req.body);

    res.send("success");
  }
);

Uploading the image is successful on the client side, but on the server side I can't receive the file object since req.file is null but req.body has content as you see the console output below

upload 111 undefined
upload 222 [Object: null prototype] { file: '[object Object]' }

can't really get why


Solution

  • The code is working.

    The code below uses the same codes in your post. It uses the same codes for axios and the backend api calls. The server side is also working fine with the same code of yours.

    The summary is that the code below works fine and it gives req.file and req.body valid references in the backend. It uploads the file and prints the console log too as shown in test results below.

    The only difference is in the following codes: Instead of the vue part, it uses the following codes.

    formData.append('username', 'testname');
    const content = '<q id="a"><span id="b">hey!</span></q>';
    const blob = new Blob([content], { type: 'text/xml' });
    formData.append('file', blob);
    

    vue code

    <el-upload action="/" :auto-upload="false" :show-file-list="false" :on-change="uploadFile" >
    

    Please have a check on this part alone and ensure that object - file referenced in uploadFile function is correct.

    Working code

    Frontend

    <!DOCTYPE html>
    <html>
      <head>
        This is test upload onload of document
        <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.2.1/axios.min.js"></script>
      </head>
      <body>
        <script>
          const uploadFile = async (file) => {
            const formData = new FormData();
            formData.append('username', 'testname');
            const content = '<q id="a"><span id="b">hey!</span></q>';
            const blob = new Blob([content], { type: 'text/xml' });
            formData.append('file', blob);
            axios
              .post(`http://localhost:3000/api/v1/upload`, formData, {
                headers: {
                  'Content-Type': 'multipart/form-data',
                },
              })
              .then((resp) => {
                var rdata = resp.data;
    
                console.log(rdata);
              })
              .catch((error) => {
                console.log(error);
              });
          };
          uploadFile();
        </script>
      </body>
    </html>
    

    Backend

    import express from 'express';
    import multer from 'multer';
    import path from 'path';
    const __dirname = import.meta.dirname;
    
    const upload = multer({
      dest: 'uploads',
    });
    
    const app = express();
    
    app.get('/', (req, res, next) => {
      res.sendFile(path.join(__dirname, './index.html'));
    });
    
    app.post('/api/v1/upload', upload.single('file'), (req, res) => {
      console.log('upload 111', req.file);
      console.log('upload 222', req.body);
    
      res.send('success');
    });
    
    app.listen(3000, () => console.log('L@3000'));
    

    Test results

    Server console:

    upload 111 {
      fieldname: 'file',
      originalname: 'blob',
      encoding: '7bit',
      mimetype: 'text/xml',
      destination: 'uploads',
      filename: 'b81ec2f4002bd6a9449ece5aefbf0ae4',
      path: 'uploads/b81ec2f4002bd6a9449ece5aefbf0ae4',
      size: 38
    }
    upload 222 [Object: null prototype] { username: 'testname' }
    

    Browser console:

    success