17

I don't know why I receive on server [Error: Multipart: Boundary not found] and bundle.js:37628 POST http://localhost:8800/exporttocsv 500 (Internal Server Error) When I make post through

<form action="/exporttocsv" method="POST"  encType="multipart/form-data">

post works correctly, but through axios doesn't work.

Please help me fix the mistake

this my code /--client

import axios from 'axios'
var formData = new FormData()

const config = { headers: { 'Content-Type': 'multipart/form-data' } };
export const ipmortToCSV = (file) => dispatch => {

formData.append('file',file)
console.log(formData.getAll('data'))

axios.post('/exporttocsv', {
          "UploadCommand": formData
      },config)
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });

//--server

const router = require('express').Router()
var csv = require('csv-express')
const controllers = require('../../controllers/exporttocsv')
var multer  = require('multer')
var upload = multer({dest : 'exporttocsv/'})

router.get('/', (req, res) => {
      controllers.exportToCsv(req,res)
  })
router.post('/',upload.single('file'),(req,res) => { 
    //controllers.importToCsv(req,res)
})

module.exports = router
Michael Cheng
  • 9,644
  • 6
  • 46
  • 48
Roman Stefanko
  • 365
  • 2
  • 3
  • 8

8 Answers8

27

You can do this ...

Instantiate a new FormData instance.

const config = { headers: { 'Content-Type': 'multipart/form-data' } };
let fd = new FormData();
fd.append('file',files[0])
return axios.post("http://localhost:5000/upload", fd, config)

Usingconcat and concat-stream

const concat = require("concat-stream")
const fd = new FormData()

fd.append("hello", "world")
fd.append("file", fs.createReadStream(file))
fd.pipe(concat(data => {
  axios.post("/hello", data, {
    headers: fd.getHeaders()
  })
}))

Using promise

const promise = new Promise((resolve) => {
  const fd = new FormData();
  fd.append("hello", "world");
  fd.append("file", fs.createReadStream(binaryFile));
  fd.pipe(concat({ encoding: 'buffer' }, data => resolve({ data, headers: fd.getHeaders() })));
});
promise.then(({ data, headers }) => axios.post('/hello', data, { headers }));

I hope I've been useful! :)

References:

Francis Rodrigues
  • 1,470
  • 4
  • 25
  • 61
13

I was struggling with this issue of multipart boundary not found with fetch api calling to a nestjs server. What I tried was to remove the

'Content-Type': 'multipart/form-data',

headers so that Fetch api automatically set the headers and it worked. Try it out

Charith Jayasanka
  • 4,033
  • 31
  • 42
  • 3
    I am using axios and i tried it there but it doesn't work as it seems axios defaults to application/json instead of recognizing the proper needed content type – Irfan wani Apr 02 '22 at 02:38
5

By default axios do not attach boundary to content type header. You have to do it manually:

axios.post(`${this.baseUrl}/${path}`, formData, {
      headers: {
        'Content-Type': `multipart/form-data; boundary=${formData.getBoundary()}`,
      },
    })

It is especially important if you talking to spring server.

In other case you will see exception:

org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
Daniel
  • 7,684
  • 7
  • 52
  • 76
  • Tried this one. The warning disappeared but Laravel `Request::hasFile()` method can't detect uploaded file. – Huy Phạm Jul 03 '22 at 17:46
  • this worked for me recently. but it might be related to an axios bug - https://github.com/axios/axios/issues/4631 – Nben Oct 25 '22 at 14:35
2

I was getting this problem with Axios via JavaScript because the content-type header was multipart-form-data but the boundary was missing.

Based on my research, a good way to handle it is to allow Axios to auto-detect the content type and set the headers correctly itself.

Here is an idea for how to accomplish this:

const formDataWithFiles = hasFiles ? new FormData() : undefined;

if (formDataWithFiles) {
    // axios will automatically set the content-type to multipart/form-data if the
    // data param is a FormData object
    // otherwise, it will use application/json
    // (study the Dev Tools > Network tab > XHR tab headers)
    Object.keys(modifiedFields)
        .forEach(field => formDataWithFiles.append(field, modifiedFields[field]));
}

const { data } = await axios({
    method,
    url: actionUrl,
    data: hasFiles ? formDataWithFiles : modifiedFields,
    headers: {
        ...axios.defaults.headers,
        ...headers,
    },
});

return data;

The above code is in a generic handleSubmit function that can be called from anywhere in the client-side.

Here is the function signature:

const { data } = await this.submitForm({
    actionUrl: this.actionUrl,
    method: this.method,
    modifiedFields: {
        ...this.modifiedUser,
    },
    hasFiles: true,
});

In the above code, there are two use cases. The first is the default case, where a normal payload is sent via a flat object. The second is the case when the form has files and you want multipart/form-data. In this case, we use the FormData Object as a vessel to instruct Axios to auto-detect the necessary headers and set the correct boundary.

If you do not specify the headers correctly, it is possible to receive an empty $request->all() Array in Laravel, or perhaps any server such as node.js.

The short answer to my answer is to use the FormData Object because it contains more information than a plain-old-JavaScript-object. With it, you can also access:

const formData = new FormData();

console.log('boundary:', formData._boundary);

As my annotation above hints towards, use the Dev Tools > Network tab > XHR tab to examine your request headers and make sure you have content-type application/json or application/x-www-form-urlencoded for regular form submits and multipart/form-data' if you are uploading a file.

agm1984
  • 15,500
  • 6
  • 89
  • 113
0

For me the main reason was what the OP did; sending the data argument of axios.post as an object ({ key: formDataObj}) instead of just formDataObj directly as the arg.

J.E.C.
  • 2,616
  • 2
  • 18
  • 21
0

For me add the following code to fixes it.

axios.post('/xxx/Upload', formData, {
    headers: {
        'Content-Type': 'multipart/form-data',
    },
    transformRequest: (data) => {
        return data
    },
})
Tyler2P
  • 2,324
  • 26
  • 22
  • 31
bang
  • 1
  • 1
  • 1
    Your answer could be improved by adding more information on what the code does and how it helps the OP. – Tyler2P May 02 '22 at 07:09
0

Okay, I would like to share my solution as I struggled with this problem for almost a day. The issue was caused by an incorrect package version. Around 27.0.0, some changes were made to the form data sending, which resulted in issues with the boundaries. I'm not sure what version you folks are using, but it might be worth checking if this is the cause of your problem.

https://github.com/axios/axios/issues/4631

parker
  • 1
0

Axios v0.27.x is not able to compute Boundary automatically of multipart/form-data. I was also facing the same issue.

Kindly update your version to v1.x.x ( I am having v1.3.4 while writing the answer)

Look in this thread for more detail - https://github.com/axios/axios/issues/4631

Hope this will help you or somebody else. Thanks!

Happy Coding :-)

Aman Kumar Gupta
  • 2,640
  • 20
  • 18