URL ⇆ encoded
Percent-encoding with the right encoder for the job. Most URL bugs come from using the whole-URL encoder on a single value, so both are offered side by side with the difference spelled out — and a breakdown that shows what your URL really contains.
- Modes
- component · whole URL
- Space
- %20 · +
- Shows
- scheme · host · path · query
Input
Encoded out
paste a full URL
Which encoder do I want?
One value
encodeURIComponent()
Escapes & = ? / : # + as well as spaces and non-ASCII. Use this for a
single query value, a path segment or a form field — anywhere the text is
data rather than structure. This is the one you want most of the time.
Whole URL
encodeURI()
Leaves the separators alone so an assembled URL stays valid. Use it only to tidy a
complete URL you already trust. Applied to a value, an & in the data
will split it into an extra parameter — a classic injection bug.
Worth knowing
Encode as you build, not after
Escape each value while assembling the URL. Encoding the finished string is always wrong: as a component it destroys the structure, as a URI it leaves dangerous characters inside values untouched.
%20 and + are not interchangeable
%20 is a space anywhere. + means a space only in a query
string, under the old form-encoding rules. In a path, + is a literal plus
— which is why email addresses with tags break when handled carelessly.
A stray % breaks decoding
Decoders expect % to be followed by two hex digits. A literal percent in
data must be written %25 first. This is the usual cause of
URIError: malformed URI sequence.
Never double-encode
Encoding twice turns %20 into %2520, and the user sees the
escape sequence in their address bar. If a value already contains %
followed by hex, check whether it has been encoded already.
Non-ASCII becomes UTF-8 bytes
é encodes to %C3%A9 — two bytes, two escapes. That is
correct. Seeing %E9 instead means something encoded it as Latin-1 and the
value will not survive a round trip.
Hosts use a different scheme
Non-ASCII domain names are not percent-encoded; they use Punycode, so
münchen.de becomes xn--mnchen-3ya.de. Only the path, query
and fragment use percent-encoding.
Characters worth recognising
| Character | Encoded | Why it matters |
|---|---|---|
space | %20 or + | The single most common escape. Plus only in a query string. |
& | %26 | Unescaped in a value, it starts a new query parameter. |
= | %3D | Separates name from value; harmless in a value but often escaped anyway. |
? | %3F | Starts the query string. Must be escaped inside a path segment. |
# | %23 | Starts the fragment. Everything after it is never sent to the server. |
/ | %2F | Path separator. Escape it when a slash is part of a single value. |
% | %25 | The escape character itself. Missing this breaks decoding entirely. |
+ | %2B | Must be escaped in a query value or it will be read back as a space. |