0
# Percent Encoding
1
2
Percent encoding and decoding utilities for handling URL-encoded strings and byte sequences according to the WHATWG URL specification.
3
4
## Capabilities
5
6
### percentDecodeString
7
8
Decodes percent-encoded sequences in a string, converting them back to their original characters.
9
10
```javascript { .api }
11
/**
12
* Percent decode a string
13
* @param {string} string - String containing percent-encoded sequences
14
* @returns {string} Decoded string with percent sequences converted to characters
15
*/
16
function percentDecodeString(string)
17
```
18
19
**Usage Examples:**
20
21
```javascript
22
const { percentDecodeString } = require("whatwg-url");
23
24
// Basic percent decoding
25
const encoded = "Hello%20World%21";
26
const decoded = percentDecodeString(encoded);
27
console.log(decoded); // "Hello World!"
28
29
// URL component decoding
30
const path = "/api/users/John%20Doe";
31
const decodedPath = percentDecodeString(path);
32
console.log(decodedPath); // "/api/users/John Doe"
33
34
// UTF-8 decoding
35
const utf8Encoded = "caf%C3%A9"; // "café" in UTF-8
36
const utf8Decoded = percentDecodeString(utf8Encoded);
37
console.log(utf8Decoded); // "café"
38
39
// Mixed encoded/unencoded content
40
const mixed = "user%40example.com";
41
const decodedMixed = percentDecodeString(mixed);
42
console.log(decodedMixed); // "user@example.com"
43
44
// Invalid sequences are left as-is
45
const invalid = "invalid%ZZ%sequence";
46
const decodedInvalid = percentDecodeString(invalid);
47
console.log(decodedInvalid); // "invalid%ZZ%sequence"
48
```
49
50
### percentDecodeBytes
51
52
Decodes percent-encoded sequences in a byte array (Uint8Array), useful for binary data processing.
53
54
```javascript { .api }
55
/**
56
* Percent decode bytes in a Uint8Array
57
* @param {Uint8Array} uint8Array - Byte array containing percent-encoded sequences
58
* @returns {Uint8Array} Decoded byte array
59
*/
60
function percentDecodeBytes(uint8Array)
61
```
62
63
**Usage Examples:**
64
65
```javascript
66
const { percentDecodeBytes } = require("whatwg-url");
67
68
// Create a byte array with percent-encoded data
69
const encoder = new TextEncoder();
70
const encodedBytes = encoder.encode("Hello%20World");
71
72
// Decode the bytes
73
const decodedBytes = percentDecodeBytes(encodedBytes);
74
75
// Convert back to string to verify
76
const decoder = new TextDecoder();
77
const result = decoder.decode(decodedBytes);
78
console.log(result); // "Hello World"
79
80
// Binary data with percent encoding
81
const binaryData = new Uint8Array([
82
0x48, 0x65, 0x6C, 0x6C, 0x6F, // "Hello"
83
0x25, 0x32, 0x30, // "%20"
84
0x57, 0x6F, 0x72, 0x6C, 0x64 // "World"
85
]);
86
87
const decodedBinary = percentDecodeBytes(binaryData);
88
console.log(decoder.decode(decodedBinary)); // "Hello World"
89
```
90
91
## Advanced Usage
92
93
### Form Data Processing
94
95
Handle form-encoded data with percent decoding:
96
97
```javascript
98
const { percentDecodeString } = require("whatwg-url");
99
100
function parseFormData(formString) {
101
const pairs = formString.split('&');
102
const result = {};
103
104
for (const pair of pairs) {
105
const [key, value] = pair.split('=');
106
const decodedKey = percentDecodeString(key);
107
const decodedValue = percentDecodeString(value || '');
108
109
if (result[decodedKey]) {
110
// Handle multiple values
111
if (Array.isArray(result[decodedKey])) {
112
result[decodedKey].push(decodedValue);
113
} else {
114
result[decodedKey] = [result[decodedKey], decodedValue];
115
}
116
} else {
117
result[decodedKey] = decodedValue;
118
}
119
}
120
121
return result;
122
}
123
124
// Usage
125
const formData = "name=John%20Doe&email=john%40example.com&city=New%20York";
126
const parsed = parseFormData(formData);
127
console.log(parsed);
128
// {
129
// name: "John Doe",
130
// email: "john@example.com",
131
// city: "New York"
132
// }
133
```
134
135
### URL Path Decoding
136
137
Safely decode URL path components:
138
139
```javascript
140
const { percentDecodeString } = require("whatwg-url");
141
142
function decodePathSegments(path) {
143
// Split path and decode each segment
144
const segments = path.split('/').map(segment => {
145
try {
146
return percentDecodeString(segment);
147
} catch (error) {
148
// Return original segment if decoding fails
149
return segment;
150
}
151
});
152
153
return segments.join('/');
154
}
155
156
// Usage
157
const encodedPath = "/users/John%20Doe/files/My%20Document.pdf";
158
const decodedPath = decodePathSegments(encodedPath);
159
console.log(decodedPath); // "/users/John Doe/files/My Document.pdf"
160
```
161
162
### Binary Data Handling
163
164
Process binary data with percent encoding:
165
166
```javascript
167
const { percentDecodeBytes } = require("whatwg-url");
168
169
function processBinaryUrl(encodedData) {
170
// Convert string to bytes if needed
171
const encoder = new TextEncoder();
172
const bytes = typeof encodedData === 'string'
173
? encoder.encode(encodedData)
174
: encodedData;
175
176
// Decode percent-encoded sequences
177
const decoded = percentDecodeBytes(bytes);
178
179
// Process the binary data
180
return {
181
size: decoded.length,
182
data: decoded,
183
preview: decoded.slice(0, 10) // First 10 bytes
184
};
185
}
186
187
// Usage with binary data
188
const binaryUrl = "data%3Aimage%2Fpng%3Bbase64%2CiVBOR";
189
const processed = processBinaryUrl(binaryUrl);
190
console.log(processed.size); // Size of decoded data
191
console.log(processed.preview); // First 10 bytes
192
```
193
194
## Error Handling
195
196
Percent decoding functions handle invalid sequences gracefully:
197
198
```javascript
199
const { percentDecodeString } = require("whatwg-url");
200
201
// Invalid hex sequences are left unchanged
202
console.log(percentDecodeString("test%GG")); // "test%GG"
203
204
// Incomplete sequences are left unchanged
205
console.log(percentDecodeString("test%2")); // "test%2"
206
207
// Mixed valid/invalid sequences
208
console.log(percentDecodeString("hello%20world%XX")); // "hello world%XX"
209
210
// Empty string handling
211
console.log(percentDecodeString("")); // ""
212
213
// Already decoded content
214
console.log(percentDecodeString("hello world")); // "hello world"
215
```
216
217
## Integration with URL Parsing
218
219
Percent decoding works seamlessly with URL parsing functions:
220
221
```javascript
222
const { parseURL, percentDecodeString } = require("whatwg-url");
223
224
// URL parsing automatically handles percent decoding for most components
225
const url = parseURL("https://example.com/path%20with%20spaces?name=John%20Doe");
226
227
// But you can manually decode if needed
228
const manuallyDecodedPath = percentDecodeString("/path%20with%20spaces");
229
console.log(manuallyDecodedPath); // "/path with spaces"
230
231
// Query parameters need manual decoding if not using URLSearchParams
232
if (url.query) {
233
const decodedQuery = percentDecodeString(url.query);
234
console.log(decodedQuery); // "name=John Doe"
235
}
236
```