2

I am uploading a csv file using FormData and XmlHttpRequest. Here is the code for that. I have a form wrapped around an html input type file, whose onchange event I am executing this code. I have tried to send the form directly as well and also read the form element into the FormData object.

      let formData = new FormData();
      let file = e.target.files[0];
      var blob = new Blob([file],{type: 'text/csv'});
      formData.append("payoutUpload", blob, 'processed.csv');

      let uri = encodeURI(`${window.serviceUri}${path}`);

      var req = new XMLHttpRequest();
      req.onload = (result) => {
        if (req.status === 500 && result && result.code === 'ECONNRESET') {
          console.log(
            'Connection was reset, hence retry the sendRequest function'
          );
        } else if (req.status === 200) {

        } else {
          console.log("Error while retrieving data");
        }
      }
      req.onerror = (e) => {
        console.log('There was an error while retrieving data from service', e);
      };
      req.open('POST', uri, true);
      req.setRequestHeader('Content-Type', 'multipart/form-data');
      req.setRequestHeader('Authorization', 'Bearer ' + token);
      req.send(formData);

When I send the request, I can see that the file is being sent in the form of Request Payload.

On the NodeJs backend, I am running Express and Formidable. I am not using body-parser, I am using express's inbuilt json and urlencoding methods.

Here is the formidable part.

const form = formidable({multiples: true});
form.parse(req, (err, fields, files) => {
    console.log(`error is ${JSON.stringify(err)}`);
    console.log(`fields is ${JSON.stringify(fields)}`);
    console.log(`files JSON: ${JSON.stringify(files)}`);
    console.log('file in request: ' + files.payoutUpload);
    console.log(`req.body: ${req.body}`);
    options.file = files.payoutUpload;
});

I get err, fields and files as empty. I have searched through all similar questions and set the request headers correctly(which is usually the issue). I can see that the request.body still has the file payload on the server end. But formidable does not parse this. Can anyone tell what I am doing wrong?

UPDATE: I have tried other packages for parsing the file, like multer, express-fileupload, all of them return files as empty. I have also tried fetch API to send my request, but with no luck.

1 Answer 1

2
req.setRequestHeader('Content-Type', 'multipart/form-data')

When you send multipart/form-data you must include a boundary parameter in the header however you can't know what value you need to set for this.

Don't set the Content-Type header at all. Allow XMLHttpRequest to generate it automatically from the FormData object.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried as you said. The xmlhttprequest object sets the content-type along with the correct boundary. However now the form.parse callback is not even called. Earlier I used to get empty files,fields and error. The request sends the file as FormData as shown in inspect network call in chrome.
the file seems to be sent in binary format. I have used this encoding in formidable as options to constructor. This has no effect though.
You are right about not setting the Content-Type header. The fetch-api or the xmlhttprequest object adds the required header along with the boundary. This is a case of formidable/multer not being able to parse the FormData. I added a text field to my form to see if it gets parsed, but even that is not getting parsed. So there is something else going on.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.