URL Decoder
Decode URL-encoded strings back to readable text. Perfect for debugging API calls, webhooks, and CloudFormation parameters.
What is URL Encoding?
URL encoding (also called percent encoding) is a mechanism for encoding information in a Uniform Resource Identifier (URI). It converts special characters into a format that can be safely transmitted over the internet. Encoded characters are represented by a percent sign (%) followed by two hexadecimal digits.
Why URL Encoding Matters
- Special characters: URLs can only contain certain characters (A-Z, a-z, 0-9, and a few special characters)
- Data integrity: Ensures data is transmitted correctly without being misinterpreted
- Security: Prevents injection attacks and data corruption
- Standards compliance: Required by RFC 3986 for valid URIs
- API compatibility: Essential for REST APIs and query parameters
URL Encoding Basics
Reserved Characters
Some characters have special meaning in URLs and must be encoded when used in data:
| Character | Encoded | Purpose in URL |
|---|---|---|
| Space | %20 | Separator |
| / | %2F | Path separator |
| ? | %3F | Query string start |
| # | %23 | Fragment identifier |
| & | %26 | Query parameter separator |
| = | %3D | Key-value separator |
| + | %2B | (Sometimes used for space) |
| % | %25 | Encoding prefix |
Unreserved Characters
These characters don't need encoding:
- A-Z, a-z: Letters
- 0-9: Digits
- - _ . ~: Special characters that are safe
Component Encoding vs Full URL Encoding
Component Encoding (encodeURIComponent)
Encodes all special characters, including those that are valid in URLs:
Use for:
- Query parameter values
- Form data
- Cookie values
- Any component of a URL
Example:
encodeURIComponent('hello world') // 'hello%20world'
encodeURIComponent('a/b?c=d') // 'a%2Fb%3Fc%3Dd'
encodeURIComponent('user@example.com') // 'user%40example.com'Encodes:
/→%2F?→%3F=→%3D&→%26#→%23- All other special characters
Full URL Encoding (encodeURI)
Preserves URL structure, only encodes invalid characters:
Use for:
- Complete URLs
- When you want to preserve
/,?,=, etc.
Example:
encodeURI('https://example.com/hello world') // 'https://example.com/hello%20world'
encodeURI('https://example.com/path?q=test') // 'https://example.com/path?q=test'
encodeURI('https://example.com/user@domain') // 'https://example.com/user%40domain'Preserves:
/(path separators)?(query string start)=(key-value separators)&(parameter separators)#(fragments)
Encodes:
- Spaces →
%20 - Special characters not valid in URLs
- Unicode characters
Common Encoding Examples
Spaces
Component encoding:
hello world → hello%20world
Full URL encoding:
https://example.com/hello world → https://example.com/hello%20world
Special Characters
Component encoding:
a/b?c=d → a%2Fb%3Fc%3Dd
Full URL encoding:
https://example.com/a/b?c=d → https://example.com/a/b?c=d
Unicode Characters
Both encodings:
café → caf%C3%A9
中文 → %E4%B8%AD%E6%96%87
Email Addresses
Component encoding:
user@example.com → user%40example.com
Full URL encoding:
mailto:user@example.com → mailto:user%40example.com
When to Use Each Encoding
Use Component Encoding When:
- Query parameter values:
const query = 'hello world';
const url = `https://api.example.com/search?q=${encodeURIComponent(query)}`;
// Result: https://api.example.com/search?q=hello%20world- Form data:
const email = 'user@example.com';
const formData = `email=${encodeURIComponent(email)}`;- Cookie values:
document.cookie = `name=${encodeURIComponent('John Doe')}`;- Path segments:
const filename = 'my file.txt';
const url = `https://example.com/files/${encodeURIComponent(filename)}`;Use Full URL Encoding When:
- Complete URLs:
const baseUrl = 'https://example.com/path?q=test';
const encoded = encodeURI(baseUrl);- Preserving URL structure:
const url = 'https://api.example.com/users/123?format=json';
const encoded = encodeURI(url); // Preserves / and ?- URLs with special characters:
const url = 'https://example.com/hello world';
const encoded = encodeURI(url); // Only encodes spaceCommon Use Cases
1. Query Parameters
Building API URLs:
const params = {
q: 'hello world',
page: 1,
filter: 'active'
};
// Component encoding for each value
const queryString = Object.entries(params)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
// Result: q=hello%20world&page=1&filter=active
const url = `https://api.example.com/search?${queryString}`;2. Form Submission
URL-encoded form data:
const formData = {
name: 'John Doe',
email: 'john@example.com',
message: 'Hello, world!'
};
const encoded = Object.entries(formData)
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
.join('&');
// Result: name=John%20Doe&email=john%40example.com&message=Hello%2C%20world%213. File Paths in URLs
Component encoding for filenames:
const filename = 'my document (2024).pdf';
const url = `https://example.com/files/${encodeURIComponent(filename)}`;
// Result: https://example.com/files/my%20document%20%282024%29.pdf4. OAuth and API Authentication
Encoding redirect URIs:
const redirectUri = 'https://myapp.com/callback?state=xyz';
const encoded = encodeURIComponent(redirectUri);
// Used in OAuth authorization URL5. CloudFormation Parameters
Encoding parameter values:
Parameters:
DatabasePassword:
Type: String
NoEcho: true
# Value will be URL-encoded when passedAWS CLI:
aws cloudformation create-stack \
--stack-name my-stack \
--template-body file://template.yaml \
--parameters ParameterKey=DatabasePassword,ParameterValue="$(echo -n 'p@ssw0rd!' | jq -sRr @uri)"6. REST API Path Parameters
Component encoding for path segments:
const userId = 'user@example.com';
const url = `https://api.example.com/users/${encodeURIComponent(userId)}`;
// Result: https://api.example.com/users/user%40example.com7. Email Links
mailto URLs:
const email = 'user@example.com';
const subject = 'Hello World';
const body = 'This is a test message.';
const mailtoUrl = `mailto:${email}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
// Result: mailto:user@example.com?subject=Hello%20World&body=This%20is%20a%20test%20message.Encoding in Different Languages
JavaScript/TypeScript
Component encoding:
encodeURIComponent('hello world') // 'hello%20world'
decodeURIComponent('hello%20world') // 'hello world'Full URL encoding:
encodeURI('https://example.com/hello world') // 'https://example.com/hello%20world'
decodeURI('https://example.com/hello%20world') // 'https://example.com/hello world'Python
Component encoding:
from urllib.parse import quote, unquote
quote('hello world') # 'hello%20world'
unquote('hello%20world') # 'hello world'Full URL encoding:
from urllib.parse import quote, unquote, urlencode
quote('hello world', safe='') # 'hello%20world'
# For query strings
urlencode({'q': 'hello world'}) # 'q=hello+world'Go
Component encoding:
import "net/url"
encoded := url.QueryEscape("hello world") // "hello%20world"
decoded, _ := url.QueryUnescape("hello%20world") // "hello world"Full URL encoding:
import "net/url"
encoded := url.PathEscape("hello world") // "hello%20world"
decoded, _ := url.PathUnescape("hello%20world") // "hello world"Java
Component encoding:
import java.net.URLEncoder;
import java.net.URLDecoder;
String encoded = URLEncoder.encode("hello world", "UTF-8"); // "hello+world"
String decoded = URLDecoder.decode("hello+world", "UTF-8"); // "hello world"Bash/Command Line
Using jq:
echo -n 'hello world' | jq -sRr @uri
# Output: hello%20worldUsing Python:
python3 -c "import urllib.parse; print(urllib.parse.quote('hello world'))"
# Output: hello%20worldCommon Mistakes to Avoid
1. Double Encoding
Wrong:
const text = 'hello world';
const encoded = encodeURIComponent(encodeURIComponent(text));
// Result: 'hello%2520world' (double-encoded)Correct:
const text = 'hello world';
const encoded = encodeURIComponent(text);
// Result: 'hello%20world' (correctly encoded)2. Encoding Complete URLs with Component Encoding
Wrong:
const url = 'https://example.com/path?q=test';
const encoded = encodeURIComponent(url);
// Result: 'https%3A%2F%2Fexample.com%2Fpath%3Fq%3Dtest' (breaks URL structure)Correct:
const url = 'https://example.com/path?q=test';
const encoded = encodeURI(url);
// Result: 'https://example.com/path?q=test' (preserves structure)3. Not Encoding Query Parameter Values
Wrong:
const query = 'hello world';
const url = `https://api.example.com/search?q=${query}`;
// Result: https://api.example.com/search?q=hello world (invalid URL)Correct:
const query = 'hello world';
const url = `https://api.example.com/search?q=${encodeURIComponent(query)}`;
// Result: https://api.example.com/search?q=hello%20world (valid URL)4. Encoding Keys in Query Strings
Wrong:
const key = 'search query';
const value = 'hello';
const url = `https://api.com?${encodeURIComponent(key)}=${value}`;
// Keys usually don't need encoding, but values doCorrect:
const key = 'search_query'; // Use valid key name
const value = 'hello world';
const url = `https://api.com?${key}=${encodeURIComponent(value)}`;5. Mixing + and %20 for Spaces
Problem:
+is sometimes used for spaces in form data%20is the standard URL encoding for spaces- Mixing them can cause issues
Solution:
- Use
%20for URL encoding - Use
+only forapplication/x-www-form-urlencodedform data - Be consistent in your application
Best Practices
1. Always Encode User Input
Never trust user input:
// Always encode user-provided data
const userInput = req.query.search;
const encoded = encodeURIComponent(userInput);2. Use Component Encoding for Query Values
Standard practice:
const params = new URLSearchParams();
params.append('q', 'hello world');
params.append('page', '1');
const queryString = params.toString();
// Automatically handles encoding3. Validate Before Decoding
Check encoding before decoding:
function safeDecode(encoded) {
try {
return decodeURIComponent(encoded);
} catch (e) {
// Handle invalid encoding
return encoded; // Return as-is if invalid
}
}4. Use URLSearchParams for Query Strings
Modern approach:
const params = new URLSearchParams({
q: 'hello world',
page: '1'
});
const url = `https://api.com/search?${params}`;
// Automatically encoded correctly5. Be Consistent
Choose one encoding method and stick with it:
- Use
encodeURIComponentfor query values - Use
encodeURIfor complete URLs - Document your encoding strategy
Security Considerations
1. Prevent Injection Attacks
Always encode user input:
// Dangerous
const userInput = req.query.search;
const sql = `SELECT * FROM users WHERE name = '${userInput}'`;
// Safe
const userInput = encodeURIComponent(req.query.search);
// Use parameterized queries for SQL2. XSS Prevention
Encode data in HTML contexts:
// URL encoding is not enough for HTML
// Use HTML entity encoding for HTML content
const userInput = '<script>alert("XSS")</script>';
// URL encoding: %3Cscript%3E...
// HTML encoding: <script>...3. Path Traversal Prevention
Encode filenames:
// Dangerous
const filename = '../../../etc/passwd';
const url = `https://example.com/files/${filename}`;
// Safe
const filename = '../../../etc/passwd';
const url = `https://example.com/files/${encodeURIComponent(filename)}`;
// Still validate and sanitize on server sideFrequently Asked Questions
What's the difference between encodeURI and encodeURIComponent?
- encodeURI: Encodes a complete URL, preserves
/,?,=, etc. - encodeURIComponent: Encodes a component (like a query value), encodes all special characters
Should I encode spaces as + or %20?
- %20: Standard URL encoding (always safe)
- +: Used in
application/x-www-form-urlencodedform data - Recommendation: Use
%20for URLs,+is automatically handled by form encoding
Do I need to encode query parameter keys?
Usually no, but:
- Keys should be valid identifiers (letters, numbers, underscore)
- If keys contain special characters, encode them
- Values should always be encoded
Can I decode multiple times?
No, decoding already-decoded strings can cause errors:
decodeURIComponent('hello%20world') // 'hello world' ✓
decodeURIComponent('hello world') // Error: Invalid encodingHow do I encode Unicode characters?
Both encoding methods handle Unicode:
encodeURIComponent('café') // 'caf%C3%A9'
encodeURIComponent('中文') // '%E4%B8%AD%E6%96%87'What characters are safe in URLs?
Unreserved characters (don't need encoding):
- A-Z, a-z, 0-9
-
- _ . ~
Everything else should be encoded.
How do I build query strings safely?
Use URLSearchParams:
const params = new URLSearchParams();
params.append('q', 'hello world');
params.append('page', '1');
const queryString = params.toString();
// Automatically handles encoding