This article is about fixing error when FormData doesn't work properly on node.js in Form-Data
  • 18-Jan-2023
Lightrun Team
Author Lightrun Team
Share
This article is about fixing error when FormData doesn't work properly on node.js in Form-Data

Error when FormData doesn’t work properly on node.js in Form-Data

Lightrun Team
Lightrun Team
18-Jan-2023

Explanation of the problem

The user encounters an issue when attempting to send FormData using axios in a Node.js environment. Upon inspecting the received data at the endpoint, it was found that the data was being sent in an inconsistent format, with the keys and values being concatenated in an unexpected manner. The user attempted to resolve the issue by using various parsing libraries, such as formidable, nestjs parser and adonisjs v5 parser, but found that the issue persisted.

To reproduce the issue, the following code can be used:

import FormData from "form-data";
import axios from "axios";

const f = new FormData();
f.append("f", "t");
axios.post("http://0.0.0.0:3333/", f).then((data) => console.log(data.data)).catch((e) => console.warn(e));

This code creates an instance of FormData, appends a key-value pair to it, and then sends it to the specified endpoint using axios. The received data at the endpoint will be in the following format:

{
  "----------------------------007181389194487799053447\r\nContent-Disposition: form-data; name": 
"\"f\"\r\n\r\nt\r\n----------------------------007181389194487799053447--\r\n"
}

The problem is specific to the use of axios in a Node.js environment, as the default FormData provided by the browser works properly.

Troubleshooting with the Lightrun Developer Observability Platform

Getting a sense of what’s actually happening inside a live application is a frustrating experience, one that relies mostly on querying and observing whatever logs were written during development.
Lightrun is a Developer Observability Platform, allowing developers to add telemetry to live applications in real-time, on-demand, and right from the IDE.

  • Instantly add logs to, set metrics in, and take snapshots of live applications
  • Insights delivered straight to your IDE or CLI
  • Works where you do: dev, QA, staging, CI/CD, and production

Start for free today

Problem solution for error when FormData doesn’t work properly on node.js in Form-Data

The issue at hand is related to the use of FormData in a Node.js environment when sending data in an HTTP post request using axios. The FormData object is not being handled correctly, resulting in an inconsistent format of the data being received at the endpoint. This can cause issues when trying to process the data, as the keys and values are concatenated in an unexpected manner.

The first solution suggests using native Node.js libraries as an alternative to FormData when sending data in an HTTP post request. Specifically, the URLSearchParams class is used to create a data object, which can be sent along with the post request using axios. This solution removes the dependency on FormData and can be implemented just as easily as using FormData. An example of this is:

const data = new URLSearchParams();
data.append(key, value);
const response = await axios.post(url, data, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}})

The second solution suggests adding the ‘Content-Length’ header to the headers object when sending the post request with axios. This header should contain the length of the FormData object being sent. This solution can be implemented by adding the following code to the headers object:

{
    "Content-Length": formdata.getLengthSync()
}

Other popular problems with Form-Data

Problem: Inconsistencies in the handling of FormData when using it in a Node.js environment

Description: FormData is a JavaScript object that is used to construct a set of key/value pairs representing form fields and their values. However, when using FormData in a Node.js environment, the received data can be in an inconsistent format, with the keys and values being concatenated in an unexpected manner. This can cause issues when trying to process the data, as the data will not be in the expected format.

Solution:

One solution is to use native Node.js libraries such as URLSearchParams class to create a data object, which can be sent along with the post request using axios. This removes the dependency on FormData and can be implemented just as easily as using FormData. Additionally, developers can use the querystring module of Node.js to format the data in the expected format.

Problem: Difficulty in adding the ‘Content-Length’ header when sending the post request

Description: FormData is a JavaScript object that is used to construct a set of key/value pairs representing form fields and their values, when sending the data using axios in Node.js environment, it could be difficult to add the ‘Content-Length’ header, which is required to properly send the data.

Solution:

One solution is to use the getLengthSync() method provided by FormData to get the length of the form data, and use it to add the ‘Content-Length’ header to the headers object when sending the post request. Additionally, developers can use the Buffer.byteLength() method to get the length of the data in bytes and use it to add the ‘Content-Length’ header.

Problem: Difficulty in handling large files when sending the data

Description: FormData is a JavaScript object that is used to construct a set of key/value pairs representing form fields and their values, when sending large files using FormData, it could cause issues with memory and performance.

Solution:

One solution is to use streams to read and write the large files, allowing you to process large files without having to load the entire file into memory at once. Additionally, developers can use the busboy library which is a streaming parser for HTML form data that can handle large files efficiently. Developers can also use the form-data package which has the capability to handle large files by processing them in chunks.

A brief introduction to Form-Data

FormData is a JavaScript object that is used to construct a set of key/value pairs representing form fields and their values. These key/value pairs can then be used to send data in an HTTP post request, simulating a traditional HTML form submit. FormData is typically used in combination with the XMLHttpRequest or Fetch API to send data to a server.

FormData has several methods that can be used to add key/value pairs, such as append(), delete(), and set(). The append() method is used to add a new key/value pair to the FormData object, while the delete() method is used to remove a key/value pair, and the set() method is used to update the value of an existing key/value pair. FormData also has a getAll() method, which returns an array of all the key/value pairs contained in the FormData object, and a get() method, which returns the value of a specific key. Additionally, FormData has a getLengthSync() method which can be used to get the length of the form data in bytes.

Most popular use cases for Form-Data include

  1. Form-Data can be used to send data in an HTTP post request, simulating a traditional HTML form submit. This can be done by creating a FormData object, adding key/value pairs to it, and then sending it as the body of the post request using the XMLHttpRequest or Fetch API.
const formData = new FormData();
formData.append("key1", "value1");
formData.append("key2", "value2");

fetch("http://example.com/submit", {
  method: "POST",
  body: formData
});
  1. Form-Data can be used to upload files to a server. This can be done by creating a FormData object, appending the file to it, and then sending it as the body of the post request.
const formData = new FormData();
const fileField = document.querySelector("input[type='file']");
formData.append("file", fileField.files[0]);

fetch("http://example.com/upload", {
  method: "POST",
  body: formData
});
  1. Form-Data can be used to send multipart/form-data encoded data, which is a format that can be used to send binary data, such as images or files, in the same HTTP request as a text data. This can be done by creating a FormData object, appending the binary data to it, and then sending it as the body of the post request.
const formData = new FormData();
formData.append("file", new Blob(["Hello World"], {type : 'text/plain'}));

fetch("http://example.com/upload", {
  method: "POST",
  body: formData
});
Share

It’s Really not that Complicated.

You can actually understand what’s going on inside your live applications.

Try Lightrun’s Playground

Lets Talk!

Looking for more information about Lightrun and debugging?
We’d love to hear from you!
Drop us a line and we’ll get back to you shortly.

By submitting this form, I agree to Lightrun’s Privacy Policy and Terms of Use.