About URL encoding and decoding
What is URL encoding, and why does text turn into %E4%B8%AD?
The URL specification (RFC 3986) only permits ASCII letters, digits and a handful of symbols. Non-Latin characters, spaces and quotation marks are not on the list. To put them in a link they first have to be turned into bytes using some character set, and then each byte written as a percent sign followed by two hexadecimal digits — that is percent-encoding, also called URL encoding. The character 中 is three bytes in UTF-8, E4 B8 AD, which is written out as %E4%B8%AD. So a run of %E4%B8... is neither mojibake nor encryption, just another way of writing the same text — and groups of three %XX are a good sign it is UTF-8-encoded CJK.
encodeURIComponent or encodeURI — which one?
This is the single easiest thing to get wrong in code. encodeURIComponent also encodes the : / ? # & = structural characters, which makes it right for a single parameter value; encodeURI leaves them alone, which makes it right for a link you have already assembled. Getting it wrong has very concrete consequences: hand a whole URL to encodeURIComponent, https:// turns into https%3A%2F%2F, breaking the link outright. Go the other way and use encodeURI on a parameter value that itself contains an & — a search term like "A&B", say — and that & survives untouched, so the server reads it as a separator and your one parameter arrives as two. The encoder above offers both; the parameter-value form is the default.
URL encoding is not encryption
URL encoding, like Base64, is an encoding, not encryption: the rules are fully public, there is no key, and anyone who has the string can reverse it in one step — this page does exactly that. Its purpose is to let special characters travel safely through a URL, and it provides no confidentiality at all. Percent-encoding an order number, a phone number or an internal ID before putting it in a link therefore protects nothing: what sits in the address bar, the server logs and the Referer header is still plain text. For something genuinely irreversible see SHA-256; for sensitive parameters, use POST over HTTPS. Incidentally, "URL decryption" is not a real thing — the correct word is decoding.
Three traps: the + sign, %20, and mojibake
Spaces have two spellings. Form submissions use application/x-www-form-urlencoded encodes a space as +, while paths and modern APIs generally use %20. The awkward part is that JavaScript's decodeURIComponent does not recognise + at all and leaves a literal plus sign behind — hence the toggle above, which reads it as a space by default. Conversely, if your content genuinely contains a plus sign (1+1), encoding turns it into %2B, and that is correct.
The character set is the second trap. UTF-8 is the default everywhere now, but plenty of older sites and systems use GBK, where 中 is two bytes, %D6%D0. Decode GBK-encoded content as UTF-8 and you get question marks or boxes. The decode side of this page lets you switch to GBK; the encode side is UTF-8 only, because that is all the browser can natively produce.
The function names, language by language. PHP's urlencode turns a space into +, rawurlencode encodes it as %20, and the matching decoders are urldecode / rawurldecode; Java's URLEncoder.encode(s, "UTF-8") follows the form-submission rules, so also +; Python uses urllib.parse.quote / unquote, where only quote_plus produces +; and JavaScript has just encodeURIComponent / decodeURIComponent, which always emits %20. When the front end and the back end disagree, this plus sign is nearly always the reason.