Anatomy of a Uniform Resource Identifier (URI)
Every web request begins with a Uniform Resource Identifier (URI). Standardized under RFC 3986, a full URL consists of five distinct syntactic components: scheme (http/https), authority (host and port), path (/products/search), query string (?q=laptop&sort=asc), and optional fragment identifier (#reviews).
Because URLs must be transmitted across heterogeneous network hardware, protocols, and proxies, the permissible character set is strictly constrained to a small subset of 7-bit US-ASCII characters. Characters outside this set (such as spaces, punctuation, or non-Latin Unicode scripts) must be escaped through percent-encoding.
Reserved vs Unreserved Characters Under RFC 3986
RFC 3986 categorizes characters into two distinct classes:
โข Unreserved Characters: Characters that never require encoding. These include uppercase letters (AโZ), lowercase letters (aโz), decimal digits (0โ9), hyphen (-), underscore (_), period (.), and tilde (~).
โข Reserved Characters: Characters that serve structural delimiting purposes within a URI. These include `:` `/` `?` `#` `[` `]` `@` `!` `$` `&` `'` `(` `)` `*` `+` `,` `;` `=`
If a reserved character is used for its structural role (such as `?` separating path from query), it remains bare. If it is used as literal data inside a parameter value (such as a password containing `&` or `#`), it MUST be percent-encoded to prevent breaking URI parsing logic.
How Percent-Encoding Transforms Bytes into Hex
Percent-encoding operates at the byte level. To encode a non-allowed character:
1. Convert the character into its UTF-8 byte sequence.
2. Express each byte as a two-digit hexadecimal number.
3. Prefix each hexadecimal pair with the percent symbol (%).
For example, the literal ampersand (&) has ASCII code 38, which equals 26 in hexadecimal; hence it encodes as `%26`. The Hindi letter "เค " consists of three UTF-8 bytes (0xE0, 0xA4, 0x85) and encodes as `%E0%A4%85`.
The Great Space Debate: %20 vs Plus (+)
One of the most persistent confusions in web development is whether a space should be encoded as `%20` or `+`:
โข In URI paths: Spaces MUST be encoded as `%20` (e.g., `/my%20documents/file.pdf`). A `+` in a path represents a literal plus character.
โข In Query Strings: Under legacy HTML form submissions (`application/x-www-form-urlencoded`), spaces are frequently serialized as `+`. However, modern RFC 3986 standards recommend `%20` uniformly across both path and query parameters to avoid ambiguity.
encodeURI() vs encodeURIComponent() in JavaScript
JavaScript developers frequently cause bugs by choosing the wrong encoding function:
โข `encodeURI()`: Encodes a complete URL. It preserves structural delimiters like `:`, `/`, `?`, and `&`, only escaping spaces and Unicode characters. Use this when you have a complete URL string that needs basic encoding.
โข `encodeURIComponent()`: Encodes a specific query parameter value. It aggressively encodes all reserved delimiters (including `&`, `=`, and `/`). Use this on individual variable values before appending them to a query string.
The Query String Rule
Always use `encodeURIComponent()` on individual query values. Using `encodeURI()` will fail to escape `&` and `=` inside parameter values, splitting your query into corrupted keys.
Common URL Encoded Characters Reference Table
Frequently used percent-encoding character replacements:
| Character | ASCII / UTF-8 Hex | Percent-Encoded Value | Common Role in URLs |
|---|---|---|---|
| Space | 0x20 | %20 (or + in forms) | Separator in text |
| Ampersand (&) | 0x26 | %26 | Separates query parameters |
| Question Mark (?) | 0x3F | %3F | Initiates the query string |
| Equals (=) | 0x3D | %3D | Binds key to value in query |
| Hash (#) | 0x23 | %23 | Initiates client-side fragment |
| Forward Slash (/) | 0x2F | %2F | Separates path hierarchy |
| Colon (:) | 0x3A | %3A | Separates scheme and port |