0
# URLSearchParams Polyfill
1
2
A comprehensive polyfill for JavaScript's URLSearchParams class that provides consistent behavior across all browsers (including IE8+) and Node.js environments. This library intelligently detects existing browser support and only polyfills when necessary, while maintaining full feature parity with the native implementation.
3
4
## Package Information
5
6
- **Package Name**: url-search-params-polyfill
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install url-search-params-polyfill`
10
11
## Core Imports
12
13
For ES2015+ and Babel:
14
15
```javascript
16
import 'url-search-params-polyfill';
17
```
18
19
For ES5/CommonJS:
20
21
```javascript
22
require('url-search-params-polyfill');
23
```
24
25
For browser environments:
26
27
```html
28
<script src="index.js"></script>
29
```
30
31
**Note**: This polyfill modifies the global `URLSearchParams` object. After importing/loading, use `URLSearchParams` directly as you would with the native implementation.
32
33
## Basic Usage
34
35
```javascript
36
// Import the polyfill (global URLSearchParams becomes available)
37
require('url-search-params-polyfill');
38
39
// Create from empty
40
const params1 = new URLSearchParams();
41
42
// Create from string
43
const params2 = new URLSearchParams('id=1&name=hello&active=true');
44
45
// Create from object
46
const params3 = new URLSearchParams({ id: 1, name: 'hello', active: true });
47
48
// Basic operations
49
params1.append('key', 'value');
50
params1.set('id', '123');
51
console.log(params1.get('id')); // '123'
52
console.log(params1.toString()); // 'key=value&id=123'
53
```
54
55
## Architecture
56
57
The polyfill uses intelligent feature detection to determine the level of native URLSearchParams support:
58
59
- **Full Native Support**: When the browser has complete URLSearchParams support, the polyfill does nothing
60
- **Partial Native Support**: Uses a Proxy wrapper to extend native functionality with missing features
61
- **No Native Support**: Provides a complete polyfill implementation with all URLSearchParams features
62
63
Key features include proper encoding/decoding of special characters, support for multiple values per key, and iterator protocol implementation for modern JavaScript compatibility.
64
65
## Capabilities
66
67
### URLSearchParams Constructor
68
69
Creates a new URLSearchParams instance from various input formats.
70
71
```javascript { .api }
72
/**
73
* Creates a new URLSearchParams instance
74
* @param {string|object|URLSearchParams|Array<[string, string]>} init - Initial data
75
*/
76
new URLSearchParams(init?)
77
```
78
79
**Constructor Variations:**
80
81
```javascript { .api }
82
// Empty instance
83
new URLSearchParams()
84
85
// From query string (with or without leading "?")
86
new URLSearchParams(string)
87
88
// From plain object
89
new URLSearchParams(object)
90
91
// From another URLSearchParams instance (copy constructor)
92
new URLSearchParams(URLSearchParams)
93
94
// From sequence of key-value pairs
95
new URLSearchParams(Array<[string, string]>)
96
```
97
98
**Usage Examples:**
99
100
```javascript
101
// Empty
102
const empty = new URLSearchParams();
103
104
// From string
105
const fromString = new URLSearchParams('?id=1&name=test');
106
const fromStringNoQ = new URLSearchParams('id=1&name=test');
107
108
// From object
109
const fromObject = new URLSearchParams({ id: 1, name: 'test', active: true });
110
111
// From another instance
112
const copy = new URLSearchParams(fromString);
113
114
// From sequence
115
const fromArray = new URLSearchParams([['id', '1'], ['name', 'test']]);
116
```
117
118
### Parameter Manipulation
119
120
#### append
121
122
Appends a key/value pair as a new search parameter.
123
124
```javascript { .api }
125
/**
126
* Appends a key/value pair as a new search parameter
127
* @param {string} name - Parameter name
128
* @param {string} value - Parameter value
129
* @returns {void}
130
*/
131
append(name, value)
132
```
133
134
#### delete
135
136
Deletes all occurrences of the given search parameter.
137
138
```javascript { .api }
139
/**
140
* Deletes all occurrences of the given search parameter
141
* @param {string} name - Parameter name to delete
142
* @returns {void}
143
*/
144
delete(name)
145
```
146
147
#### set
148
149
Sets the value associated with a search parameter, replacing all existing values.
150
151
```javascript { .api }
152
/**
153
* Sets the value associated with a search parameter
154
* @param {string} name - Parameter name
155
* @param {string} value - Parameter value
156
* @returns {void}
157
*/
158
set(name, value)
159
```
160
161
**Usage Examples:**
162
163
```javascript
164
const params = new URLSearchParams();
165
166
// Add multiple values for same key
167
params.append('id', '1');
168
params.append('id', '2');
169
console.log(params.toString()); // 'id=1&id=2'
170
171
// Replace all values for a key
172
params.set('id', '3');
173
console.log(params.toString()); // 'id=3'
174
175
// Delete all values for a key
176
params.delete('id');
177
console.log(params.toString()); // ''
178
```
179
180
### Parameter Access
181
182
#### get
183
184
Returns the first value associated with the given search parameter.
185
186
```javascript { .api }
187
/**
188
* Returns the first value associated with the given search parameter
189
* @param {string} name - Parameter name
190
* @returns {string|null} First value or null if not found
191
*/
192
get(name)
193
```
194
195
#### getAll
196
197
Returns all values associated with the given search parameter.
198
199
```javascript { .api }
200
/**
201
* Returns all values associated with the given search parameter
202
* @param {string} name - Parameter name
203
* @returns {Array<string>} Array of all values (empty array if not found)
204
*/
205
getAll(name)
206
```
207
208
#### has
209
210
Returns whether the given search parameter exists.
211
212
```javascript { .api }
213
/**
214
* Returns whether the given search parameter exists
215
* @param {string} name - Parameter name
216
* @returns {boolean} True if parameter exists
217
*/
218
has(name)
219
```
220
221
**Usage Examples:**
222
223
```javascript
224
const params = new URLSearchParams('id=1&id=2&name=test');
225
226
console.log(params.get('id')); // '1' (first value)
227
console.log(params.getAll('id')); // ['1', '2'] (all values)
228
console.log(params.has('name')); // true
229
console.log(params.has('age')); // false
230
console.log(params.get('age')); // null
231
```
232
233
### String Representation
234
235
#### toString
236
237
Returns a query string suitable for use in a URL.
238
239
```javascript { .api }
240
/**
241
* Returns a query string suitable for use in a URL
242
* @returns {string} Query string representation
243
*/
244
toString()
245
```
246
247
**Usage Examples:**
248
249
```javascript
250
const params = new URLSearchParams({ name: 'hello world', active: true });
251
console.log(params.toString()); // 'name=hello+world&active=true'
252
253
// Use in URLs
254
const url = 'https://api.example.com/search?' + params.toString();
255
```
256
257
### Iteration and Ordering
258
259
#### forEach
260
261
Executes a callback function for each name/value pair.
262
263
```javascript { .api }
264
/**
265
* Executes a callback function for each name/value pair
266
* @param {function} callback - Function to execute for each pair
267
* @param {object} thisArg - Optional object to use as 'this' in callback
268
* @returns {void}
269
*/
270
forEach(callback, thisArg?)
271
```
272
273
**Callback signature:**
274
275
```javascript { .api }
276
/**
277
* @param {string} value - Parameter value
278
* @param {string} key - Parameter name
279
* @param {URLSearchParams} searchParams - The URLSearchParams instance
280
*/
281
callback(value, key, searchParams)
282
```
283
284
#### sort
285
286
Sorts all name-value pairs by their names.
287
288
```javascript { .api }
289
/**
290
* Sorts all name-value pairs by their names
291
* @returns {void}
292
*/
293
sort()
294
```
295
296
**Usage Examples:**
297
298
```javascript
299
const params = new URLSearchParams('z=3&a=1&b=2&a=4');
300
301
// Iterate over all pairs
302
params.forEach((value, key) => {
303
console.log(`${key}: ${value}`);
304
});
305
// Output: z: 3, a: 1, b: 2, a: 4
306
307
// Sort parameters alphabetically
308
params.sort();
309
console.log(params.toString()); // 'a=1&a=4&b=2&z=3'
310
```
311
312
### Iterator Protocol
313
314
#### keys
315
316
Returns an iterator for all parameter names.
317
318
```javascript { .api }
319
/**
320
* Returns an iterator for all parameter names
321
* @returns {Iterator<string>} Iterator of parameter names
322
*/
323
keys()
324
```
325
326
#### values
327
328
Returns an iterator for all parameter values.
329
330
```javascript { .api }
331
/**
332
* Returns an iterator for all parameter values
333
* @returns {Iterator<string>} Iterator of parameter values
334
*/
335
values()
336
```
337
338
#### entries
339
340
Returns an iterator for all name-value pairs.
341
342
```javascript { .api }
343
/**
344
* Returns an iterator for all name-value pairs
345
* @returns {Iterator<[string, string]>} Iterator of [name, value] pairs
346
*/
347
entries()
348
```
349
350
#### Symbol.iterator
351
352
Makes URLSearchParams iterable with for...of loops (same as entries()).
353
354
```javascript { .api }
355
/**
356
* Symbol.iterator implementation for for...of loops
357
* @returns {Iterator<[string, string]>} Iterator of [name, value] pairs
358
*/
359
[Symbol.iterator]()
360
```
361
362
**Usage Examples:**
363
364
```javascript
365
const params = new URLSearchParams('a=1&b=2&a=3');
366
367
// Iterate over keys
368
for (const key of params.keys()) {
369
console.log(key); // 'a', 'b', 'a'
370
}
371
372
// Iterate over values
373
for (const value of params.values()) {
374
console.log(value); // '1', '2', '3'
375
}
376
377
// Iterate over entries
378
for (const [key, value] of params.entries()) {
379
console.log(`${key}=${value}`); // 'a=1', 'b=2', 'a=3'
380
}
381
382
// Direct iteration (same as entries)
383
for (const [key, value] of params) {
384
console.log(`${key}=${value}`); // 'a=1', 'b=2', 'a=3'
385
}
386
```
387
388
### Properties
389
390
#### size
391
392
Returns the total number of search parameter entries.
393
394
```javascript { .api }
395
/**
396
* Total number of search parameter entries
397
* @type {number}
398
*/
399
readonly size
400
```
401
402
**Usage Examples:**
403
404
```javascript
405
const params = new URLSearchParams('a=1&b=2&a=3');
406
console.log(params.size); // 3 (counts all entries, including duplicates)
407
408
const empty = new URLSearchParams();
409
console.log(empty.size); // 0
410
```
411
412
### Polyfill Detection
413
414
#### polyfill
415
416
Boolean property indicating this is the polyfill implementation.
417
418
```javascript { .api }
419
/**
420
* Always true - indicates this is the polyfill implementation
421
* @type {boolean}
422
*/
423
URLSearchParams.prototype.polyfill
424
```
425
426
**Usage Examples:**
427
428
```javascript
429
require('url-search-params-polyfill');
430
431
const params = new URLSearchParams();
432
console.log(params.polyfill); // true (when polyfill is active)
433
```
434
435
## Types
436
437
```javascript { .api }
438
/**
439
* URLSearchParams constructor options
440
*/
441
type URLSearchParamsInit =
442
| string
443
| object
444
| URLSearchParams
445
| Array<[string, string]>
446
| undefined;
447
448
/**
449
* Callback function for forEach method
450
*/
451
type ForEachCallback = (
452
value: string,
453
key: string,
454
searchParams: URLSearchParams
455
) => void;
456
457
/**
458
* Iterator types
459
*/
460
type KeyIterator = Iterator<string>;
461
type ValueIterator = Iterator<string>;
462
type EntryIterator = Iterator<[string, string]>;
463
```
464
465
## Error Handling
466
467
The polyfill may throw the following errors:
468
469
### Constructor Errors
470
471
```javascript { .api }
472
/**
473
* Thrown when sequence initializer contains invalid elements
474
*/
475
TypeError: "Failed to construct 'URLSearchParams': Sequence initializer must only contain pair elements"
476
```
477
478
**Occurs when:** Array elements are not 2-element arrays:
479
480
```javascript
481
// This will throw
482
new URLSearchParams([['key1'], ['key2', 'value2', 'extra']]);
483
484
// This works
485
new URLSearchParams([['key1', 'value1'], ['key2', 'value2']]);
486
```
487
488
### Property Access Errors
489
490
```javascript { .api }
491
/**
492
* Thrown when size getter is called incorrectly
493
*/
494
TypeError: "Illegal invocation at URLSearchParams.invokeGetter"
495
```
496
497
**Occurs when:** Accessing size property on the prototype directly:
498
499
```javascript
500
// This will throw
501
console.log(URLSearchParams.prototype.size);
502
503
// This works
504
const params = new URLSearchParams();
505
console.log(params.size);
506
```
507
508
## Known Issues and Compatibility
509
510
### fetch() Integration
511
512
When using this polyfill with the fetch API in browsers that support fetch but not URLSearchParams (Edge 14-16, Chrome 40-48, Opera 27-35), you may need to manually set the Content-Type header:
513
514
```javascript
515
function safeFetch(url, options = {}) {
516
const { headers = {}, body } = options;
517
const finalHeaders = headers instanceof Headers ? headers : new Headers(headers);
518
519
if (body instanceof URLSearchParams) {
520
finalHeaders.set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
521
}
522
523
return fetch(url, { ...options, headers: finalHeaders, body });
524
}
525
```
526
527
### Special Character Handling
528
529
The polyfill correctly handles encoding/decoding of special characters:
530
531
- Spaces become `+` in the query string
532
- Plus signs (`+`) in values are properly encoded as `%2B`
533
- Special characters like `!`, `'`, `(`, `)`, `~` are percent-encoded
534
- Ampersands (`&`) in values are properly encoded as `%26`