Error when FormData doesn’t work properly on node.js in Form-Data
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
- 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
});
- 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
});
- 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
});
It’s Really not that Complicated.
You can actually understand what’s going on inside your live applications.