Why URLs Need Encoding
A URL can only contain a limited set of characters safely: letters, digits, and a handful of punctuation marks with defined structural meaning. Anything else — spaces, accented letters, symbols, or a structural character appearing as literal data — has to be represented as a percent sign followed by its byte value in hexadecimal.
Common Encodings
& → %26
/ → %2F
? → %3F
# → %23
+ → %2B
Encoding is reversible and lossless — decoding an encoded string always recovers the exact original bytes, which is what makes it safe to pass arbitrary data through a URL without corrupting it, however unusual the original characters were.
Component Encoding vs Full URI Encoding
These two modes exist because a full URL and a single value inside it need different characters left alone.
Single value / parameter — encodeURIComponent
Escapes everything that is not a plain letter, digit, or a small set of safe punctuation, including /, ?, &, and #. Use this for a value going into a query string, since those characters would otherwise be misread as part of the URL's own structure.
Full URL — encodeURI
Leaves structural characters like /, ?, #, and & alone, since a complete URL is expected to contain them as its own syntax. Use this when encoding an entire address rather than one piece of data inside it.
Using the wrong mode breaks the URL either way
Component-encoding a full URL turns its own slashes and colons into %2F and %3A, producing an unusable string. URI-encoding a single parameter value that happens to contain an & leaves it unescaped, silently splitting the query string at the wrong point.
Form Encoding and the Plus Sign
HTML forms submitted with the default application/x-www-form-urlencoded content type use a slightly different convention than standard URL percent-encoding: a space becomes a literal + rather than %20, and a literal + in the original data has to be escaped as %2B to avoid being read as a space.
This is a common source of confusion when debugging a query string built from form data versus one built directly by JavaScript's encoding functions, since the two conventions disagree on exactly one character. When decoding form-submitted data, replace + with a space before percent-decoding the rest, or use a decoder built specifically for form encoding rather than the general-purpose URL decoder.