Hudson Miranda
Hudson Miranda

Reputation: 11

Multipart/form-data sends empty data using axios

I'm trying to make a request, however, it looks like my body isn't being sent. I made an API that returns me exactly what I'm sending, however the body is returning empty.

Notes:

  1. Through an API, I need to send a file with .txt or .msg format.
  2. I have hidden some of the information below as this is sensitive business data.
const axios = require('axios');

async function UploadFile(urlNovaTarefa, siteUrl, clientId, clientSecret, nomeCentral, grupoId, AssuntoId, usuario, solicitante, copia, solicitacao, anexoNome, anexoConteudo, dataEntrada, enviarNotificacao, cnpjPedido, responsavel){
    // formData
    const form = new FormData();
    form.append('NomeCentral', nomeCentral);
    form.append('GrupoId', grupoId);
    form.append('AssuntoId', AssuntoId);
    form.append('Usuario', usuario);
    form.append('Solicitante', solicitante);
    form.append('Copia', copia); 
    form.append('Solicitacao', solicitacao);
    form.append('AnexoNome', anexoNome);
    form.append('AnexoConteudo', anexoConteudo);
    form.append('DataEntrada', dataEntrada);
    form.append('EnviarNotificacao', enviarNotificacao);
    form.append('CNPJPedido', cnpjPedido);
    form.append('Responsavel', responsavel);

    //console.log(form);
    
    let response = await axios.post(urlNovaTarefa, form, {
          headers: {
            'SiteUrl': siteUrl,
            'Client-Id': clientId,
            'Client-Secret': clientSecret,
            'Content-Type': "multipart/form-data; boundary=CSC",
            'Access-Control-Allow-Origin': "*",
          },
        });

        let data = response.data;
        console.log(data);
  }


  UploadFile("https://example.net/ct/csc/novaTarefa", "https://example.com/sites/centralcsc/", "1234-1234-1234-1234", "abcd-abcd-abcd-abcd=", "ServicosClientes", "4", "3", "[email protected]", "[email protected]", "[email protected]", "Test", "Test.txt", "C:\\Users\\User\\Desktop\\Test.txt", "07/10/2021 14:30", "N", "[{\"NumeroCNPJ\":\"12345678910112\",\"NumeroPedido\":[]}]", "[email protected]")
  .then(response => console.log(response))
  .catch(err => console.log(err))

What should be being sent on my body (form-data) is this:

  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="NomeCentral"\r\n' +
    '\r\n',
  'ServicosClientes',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="GrupoId"\r\n' +
    '\r\n',
  '4',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="AssuntoId"\r\n' +
    '\r\n',
  '3',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="Usuario"\r\n' +
    '\r\n',
  '[email protected]',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="Solicitante"\r\n' +
    '\r\n',
  '[email protected]',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="Copia"\r\n' +
    '\r\n',
  '[email protected]',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="Solicitacao"\r\n' +
    '\r\n',
  'Test',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="AnexoNome"\r\n' +
    '\r\n',
  'Test.txt',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="AnexoConteudo"\r\n' +
    '\r\n',
  'C:\\Users\\User\\Desktop\\Test.txt',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="DataEntrada"\r\n' +
    '\r\n',
  '07/10/2021 14:30',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="EnviarNotificacao"\r\n' +
    '\r\n',
  'N',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="CNPJPedido"\r\n' +
    '\r\n',
  '[{"NumeroCNPJ":"12345678910112","NumeroPedido":[]}]',
  [Function: bound ],
  '----------------------------553386948041586350665922\r\n' +
    'Content-Disposition: form-data; name="Responsavel"\r\n' +
    '\r\n',
  '[email protected]',
  [Function: bound ]
]

This is the return of my API! The Body is empty.

 Resultado: 0,
 Mensagem: 'Success',
 Headers: {
   connection: 'Keep-Alive',
   'transfer-encoding': 'chunked',
   accept: 'application/json, text/plain, */*',
   host: 'example.net',
   'max-forwards': '10',
   'user-agent': 'axios/0.23.0',
   'x-client-ip': '000.00.00.000',
   'x-client-port': '00000',
   siteurl: 'https://example.com/sites/centralcsc/',
   'client-id': '1234-1234-1234-1234',
   'client-secret': 'abcd-abcd-abcd-abcd=',
   'access-control-allow-origin': '*',
   'x-waws-unencoded-url': '/ct/csc/novaTarefa',
   'client-ip': '000.00.00.000:00000',
   'x-arr-log-id': 'xxxxxxxxxxxxxxxxxxxx',
   'disguised-host': 'example.net',
   'x-site-deployment-id': 'example',
   'was-default-hostname': 'example.net',
   'x-original-url': '/ct/csc/novaTarefa',
   'x-forwarded-for': '000.00.00.000:00000',
   'x-arr-ssl': '2048|256|C=US, O=Microsoft Corporation, CN=Microsoft RSA TLS CA 02|CN=*.example.net',
   'x-forwarded-proto': 'https',
   'x-appservice-proto': 'https',
   'x-forwarded-tlsversion': '1.2',
   'request-id': '|999999999-99999999999999.1.',
   'content-type': 'multipart/form-data; boundary=CSC'
 },
 Body: {}
}
undefined

Upvotes: 1

Views: 1382

Answers (2)

hamid saifi
hamid saifi

Reputation: 464

I was having the same issue. I spend my whole day just to get it fixed but in the end I just downgrade my Axios version to ^0.21.4 and it started working like a charm. the problem was the Axios latest version bug.

Upvotes: 1

balexandre
balexandre

Reputation: 75073

Hi 👋 welcome to StackOverflow!

I don't think you're code is wrong, just that your " I made an API that returns me exactly what I'm sending " might not be right... if you search for "post bin" you will find a lot of free services that give you a temporary URL so you can send data and check it

one of those services is https://hookbin.com/

I just created a really simple code based on your question:

const axios = require('axios');
const FormData = require('form-data');

async function UploadFile(dataToUpload) {
   const { clientId, clientSecret } = dataToUpload;
    
   const form = new FormData();
   Object.keys(dataToUpload).forEach(key => form.append(key, dataToUpload[key]));

   const response = await axios({
      method: 'POST',
      url: 'https://hookb.in/nPDl9aLjgVsZ7Qrr7ja6',
      data: form,
      headers: {
         ...form.getHeaders(),
         'Client-Id': clientId,
         'Client-Secret': clientSecret,
      },
   });

   console.log(response.data);
}


(async () => {
    await UploadFile({
        clientId: '1234',
        clientSecret: 'abc',
        nomeCentral: 'ServicoClientes',
        grupoId: '4',
        assuntoId: '5',
        usuario: '[email protected]',
        solicitante: '[email protected]',
        copia: '[email protected]',
        solicitacao: 'teste',
        dataEntrada: '07/10/2021 14:30',
        enviarNotificacao: 'N',
        cnpjPedido: '[{\"NumeroCNPJ\":\"12345678910112\",\"NumeroPedido\":[]}]',
        responsavel: '[email protected]'
    })
})();

Note that the code above is the same as below, the code style is just a personal preference

await axios.post('https://hookb.in/nPDl9aLjgVsZ7Qrr7ja6', form, {
  headers: {
     ...form.getHeaders(),
     'Client-Id': clientId,
     'Client-Secret': clientSecret,
  },
});

and Hookbin does shows all the data in the body

body screenshot


just to give you some hints on how to improve your code:

  • functions should accept max 3 inputs, more than that, try to pass an object as the input, as it will be easier to read and know what the function needs (even better if you use typescript)
  • every time you repeating lines, try to come up with something easier, in your example, see my forEach loop and I send 1 or 50 properties with just one line
  • it's easier to send the date as integer and save that in the database rather than a formated date, as the database could be in a different country and you will start to have issue with conversions, try send, whenever possible something like: dataEntrada: Date.now()
  • same as boolean values, enviarNotificacao: 'N' would be best sent as enviarNotificacao: false as it will be easier and faster if you ever need to index that value in the database
  • remember that form.getHeaders() will automatically append the correct headers on the request, no need to specify more, see the headers in the link or the image below (in case the link expires)

headers screenshot

Upvotes: 1

Related Questions