Table of Contents#
- Understanding URL Encoding for Whitespace
- How Axios Encodes Query Parameters by Default
- The + vs %20 Confusion: Why It Matters
- Controlling Query Parameter Encoding in Axios
- Practical Examples
- Common Pitfalls and Solutions
- Conclusion
- References
1. Understanding URL Encoding for Whitespace#
URLs are designed to be ASCII-only and cannot include special characters like spaces, ampersands, or slashes. To include these characters safely, they are encoded into a "percent-encoded" format (e.g., %20 for space) or, in some cases, replaced with a reserved character (e.g., + for space).
Key Encoding Standards:#
- Percent-Encoding (RFC 3986): Defines that spaces in URLs (including query parameters) should be encoded as
%20. This is the modern, standardized approach. - application/x-www-form-urlencoded (HTML Forms): Historically, HTML forms submitted via
GETorPOSTencode spaces as+and special characters as percent-encoded values (e.g.,=becomes%3D). This format was designed for form data, not general URL query parameters.
2. How Axios Encodes Query Parameters by Default#
Axios, by default, uses the qs library to serialize query parameters (the params object in a GET request). The qs library follows modern URL standards and uses percent-encoding for spaces, resulting in %20.
Why %20 by Default?#
The qs library relies on encodeURIComponent, a built-in JavaScript function that encodes spaces as %20 (per RFC 3986). For example:
const axios = require('axios');
axios.get('https://api.example.com/search', {
params: { query: 'hello world' }
}); Resulting URL: https://api.example.com/search?query=hello%20world
3. The + vs %20 Confusion: Why It Matters#
The confusion arises because some servers or APIs may incorrectly interpret + as a space in query parameters, even though RFC 3986 specifies %20 as the standard. Here’s why this matters:
-
Server-Side Parsing Differences:
- Servers following RFC 3986 (e.g., modern frameworks like Express.js, Django) will parse
%20as a space and+as a literal plus sign. - Older or non-standard servers may treat
+as a space in query parameters (mimicking form data behavior), leading to inconsistent results.
- Servers following RFC 3986 (e.g., modern frameworks like Express.js, Django) will parse
-
Example of Misinterpretation:
If you sendquery=hello+worldto a strict RFC 3986 server, it will interpret the value ashello+world(with a plus), nothello world(with a space). This breaks your request!
4. Controlling Query Parameter Encoding in Axios#
Axios allows you to customize query parameter encoding using the paramsSerializer option. This lets you override the default qs behavior to use + instead of %20 (or vice versa) if needed.
Key Tools for Custom Serialization:#
qsLibrary: Axios’s default serializer, with options to tweak encoding.querystringModule: A Node.js built-in module that mimicsapplication/x-www-form-urlencodedencoding (spaces as+).
How to Use paramsSerializer:#
The paramsSerializer option accepts a function that takes the params object and returns a serialized string.
5. Practical Examples#
Example 1: Default Axios Behavior (%20 Encoding)#
const axios = require('axios');
// Default: spaces encoded as %20
axios.get('https://api.example.com/search', {
params: { query: 'hello world', category: 'books' }
})
.then(response => console.log(response.config.url))
// Logs: https://api.example.com/search?query=hello%20world&category=books Example 2: Encode Spaces as + (Using querystring)#
If your server expects + for spaces (e.g., legacy systems), use Node.js’s querystring module:
const axios = require('axios');
const querystring = require('querystring');
axios.get('https://api.example.com/search', {
params: { query: 'hello world' },
paramsSerializer: (params) => querystring.stringify(params)
})
.then(response => console.log(response.config.url))
// Logs: https://api.example.com/search?query=hello+world Why this works: querystring.stringify encodes spaces as + (mimicking application/x-www-form-urlencoded).
Example 3: Custom qs Configuration#
For granular control, use qs.stringify with custom options (e.g., force + encoding):
const axios = require('axios');
const qs = require('qs');
axios.get('https://api.example.com/search', {
params: { query: 'hello world' },
paramsSerializer: (params) => qs.stringify(params, {
encode: false, // Disable default encodeURIComponent
format: 'RFC1738' // Use RFC 1738 (encodes spaces as +)
})
})
.then(response => console.log(response.config.url))
// Logs: https://api.example.com/search?query=hello+world ⚠️ Note: format: 'RFC1738' is a qs option that enforces application/x-www-form-urlencoded rules (spaces as +).
Example 4: Mixed Encoding (Spaces as %20, Special Characters as +)#
Rarely, you may need to encode spaces as %20 but other characters as +. Use a custom encoder:
const axios = require('axios');
const qs = require('qs');
const customEncoder = (str) => {
return encodeURIComponent(str).replace(/%20/g, '+'); // Replace %20 with +
};
axios.get('https://api.example.com/search', {
params: { query: 'hello world!', page: 1 },
paramsSerializer: (params) => qs.stringify(params, { encode: customEncoder })
})
.then(response => console.log(response.config.url))
// Logs: https://api.example.com/search?query=hello+world%21&page=1 6. Common Pitfalls and Solutions#
Pitfall 1: Assuming + is Always a Space#
Problem: Sending + expecting a space, but the server parses it as a literal +.
Solution: Use %20 (Axios default) unless the server explicitly requires +.
Pitfall 2: Manual Encoding + Axios Serialization#
Problem: Manually encoding parameters (e.g., encodeURIComponent('hello world')) and passing them to params, leading to double encoding (hello%2520world).
Solution: Never manually encode params—let Axios handle it via paramsSerializer.
Pitfall 3: Ignoring Server Documentation#
Problem: Not checking if the API expects + or %20 for spaces.
Solution: Always refer to the API’s documentation for encoding requirements. Most modern APIs follow RFC 3986 (%20).
7. Conclusion#
Handling whitespace in Axios GET query parameters boils down to understanding encoding standards and server expectations:
- Default Behavior: Axios uses
%20(viaqsandencodeURIComponent), aligning with RFC 3986. - Custom Encoding: Use
paramsSerializerwithqsorquerystringto force+encoding for legacy servers. - Key Takeaway: Always verify the server’s expected encoding format to avoid parsing errors.