How to send urlencoded data using Axios
By Flavio Copes
Learn how to send urlencoded data with Axios: pass a URLSearchParams object, or set the x-www-form-urlencoded header and let Axios 1.x serialize nested objects.
To send urlencoded data using Axios, pass a URLSearchParams object as data. Axios 1.x detects that type and sends it as application/x-www-form-urlencoded for you. For nested objects, set the content-type header and Axios serializes the object with bracket notation. You only need qs on Axios versions older than 1.0.
I had this problem: an API I had to call from a Node.js app was only accepting data using the urlencoded format.
What is urlencoded data?
It’s the format HTML forms use when they submit: key/value pairs separated by =, joined by &:
item1=value1&item2=value2
When you pass a plain JavaScript object as data, Axios serializes it to JSON by default. An API that expects form data will reject that body, or parse it into nothing.
The modern way: URLSearchParams
In browsers and modern Node.js, build the body with URLSearchParams:
const axios = require('axios')
axios({
method: 'post',
url: 'https://my-api.com',
data: new URLSearchParams({
item1: 'value1',
item2: 'value2'
})
})
Axios sees the URLSearchParams instance and sets the right content type. No extra package for flat key/value pairs.
With ES Modules:
import axios from 'axios'
await axios.post(
'https://my-api.com',
new URLSearchParams({
item1: 'value1',
item2: 'value2'
})
)
Nested objects
URLSearchParams is flat. Nested objects need the bracket notation servers like PHP and Rails understand: user[name]=Flavio.
Since Axios 1.0, you get that by passing a plain object and setting the content-type header yourself. Axios sees the header and serializes the object into urlencoded format:
axios({
method: 'post',
url: 'https://my-api.com',
data: {
user: { name: 'Flavio' }
},
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
})
The body becomes user%5Bname%5D=Flavio, the encoded form of user[name]=Flavio.
On older Axios versions: qs
Axios 0.x doesn’t do that serialization. There, use the qs library:
npm install qs
Stringify the data and set the header:
const qs = require('qs')
const axios = require('axios')
axios({
method: 'post',
url: 'https://my-api.com',
data: qs.stringify({
user: { name: 'Flavio' }
}),
headers: {
'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
}
})
qs.stringify({ user: { name: 'Flavio' } }) gives the same user%5Bname%5D=Flavio string.
A pitfall to avoid
If you pass a plain object as data and don’t set the header, Axios sends a JSON body. An API that expects form data can’t parse it.
Pass URLSearchParams, or set the content-type header so Axios serializes the object for you. If the API responds with an error saying a required field is missing even though you’re sending it, this mismatch is the first thing to check.
Want me to talk about your product? You can sponsor this site.
Related posts about js: