What each mode does to each character
Component is almost always the answer. Whole URL leaves &, =, ?, / and # alone, since in an assembled address they are structure rather than data. Strict RFC 3986 additionally escapes !, ', (, ) and *, which neither built-in JavaScript function touches because RFC 2396 called them "marks" and RFC 3986 §2.2 later made them reserved sub-delimiters. OAuth 1.0 and AWS Signature Version 4 sign the strict form. A bare character below means that mode leaves it alone.
| Character | Component | Whole URL | Form | RFC 3986 |
|---|---|---|---|---|
| space | %20 | %20 | + | %20 |
| ! | ! | ! | %21 | %21 |
| " | %22 | %22 | %22 | %22 |
| # | %23 | # | %23 | %23 |
| $ | %24 | $ | %24 | %24 |
| % | %25 | %25 | %25 | %25 |
| & | %26 | & | %26 | %26 |
| ' | ' | ' | %27 | %27 |
| ( | ( | ( | %28 | %28 |
| ) | ) | ) | %29 | %29 |
| * | * | * | * | %2A |
| + | %2B | + | %2B | %2B |
| , | %2C | , | %2C | %2C |
| / | %2F | / | %2F | %2F |
| : | %3A | : | %3A | %3A |
| ; | %3B | ; | %3B | %3B |
| < | %3C | %3C | %3C | %3C |
| = | %3D | = | %3D | %3D |
| > | %3E | %3E | %3E | %3E |
| ? | %3F | ? | %3F | %3F |
| @ | %40 | @ | %40 | %40 |
| [ | %5B | %5B | %5B | %5B |
| \ | %5C | %5C | %5C | %5C |
| ] | %5D | %5D | %5D | %5D |
| ^ | %5E | %5E | %5E | %5E |
| ` | %60 | %60 | %60 | %60 |
| { | %7B | %7B | %7B | %7B |
| | | %7C | %7C | %7C | %7C |
| } | %7D | %7D | %7D | %7D |
| ~ | ~ | ~ | %7E | ~ |
Why %2520 appears, and what to do about it
%2520 is a space encoded twice. The first pass gives %20; the second sees a literal percent sign, itself reserved, and encodes it as %25. The same happens to every escape: %26 becomes %2526.
It comes from a value encoded in the application and encoded again by a framework, a proxy or a redirect that rebuilds the URL. Decoding here repeats until nothing changes and shows every layer. Two layers is normal; three means something in the chain is encoding an already-encoded value, and the fix belongs at that step.
What the URL parser rewrites
Break down uses the browser's URL parser, which rewrites as well as splits. A default port disappears, so https://example.com:443/ and https://example.com/ will not compare equal as strings. A non-ASCII hostname becomes Punycode: münchen.de is sent as xn--mnchen-3ya.de, since the host is the one part of a URL that is not percent-encoded (RFC 3492).
Common problems
- A value split into two parameters. An unescaped
&ends the value. Encode the value before concatenating, not the finished URL afterwards. - Decoding left the ampersands alone.
decodeURIrefuses%26,%3D,%2Fand the rest of the reserved set, since that would change the URL's structure. Use Component mode. - Text encoded from Latin-1.
caf%E9came from a system whereéis one byte; UTF-8 spells it%C3%A9. Re-encode at the source. - A space as
+in a path. That substitution belongs to form bodies and query strings. In a path segment a plus is a plus, somy file.pdfmust bemy%20file.pdf.
Frequently asked questions
What is the difference between encodeURI and encodeURIComponent?
The safe set. encodeURIComponent escapes everything except letters, digits and - _ . ! ~ * ' ( ). encodeURI also leaves the delimiters ; , / ? : @ & = + $ # alone, which is why running it on a single value is the most common cause of a broken query string.
Should a space be %20 or +?
%20 everywhere, except in an application/x-www-form-urlencoded body or a form-produced query string, where both work. In a path segment or a fragment %20 is the only correct form.
Is percent-encoding a security measure?
No. It is reversible by anyone, with no key, and solves one problem: getting arbitrary characters through a URL intact. A decoded value still has to be validated before it reaches SQL, HTML or a shell.
Does anything I paste here get uploaded?
No. Everything runs in your browser, with no network request. The text is not written to the address bar either: the mode and direction are shareable in the link, the payload is not, because a query string is exactly the kind of thing that carries a token you would not want in browser history.