URL 编码与解码
对 URL 和查询串做百分号编码或解码,并对比 encodeURI 与 encodeURIComponent 的区别。
What percent-encoding is
URLs can only contain a limited set of characters. Anything else is replaced with a % followed by two hex digits. A space becomes %20 and a slash becomes %2F.
https://example.com/a b?x=hello world
https://example.com/a%20b?x=hello%20world
The two functions, and when to use each
JavaScript gives you two, and mixing them up is a classic source of bugs.
| Function | Escapes | Leaves intact | Use for |
|---|---|---|---|
encodeURI | Reserved characters | / ? # $ & + , ; = : @ | A whole URL |
encodeURIComponent | Everything except A-Z a-z 0-9 - _ . ! ~ * ' ( ) | Nothing but unreserved | A single value |
The rule of thumb: encodeURI for a complete URL, encodeURIComponent for a value going into it.
// Correct - a value inside a query string
url += "?q=" + encodeURIComponent(userInput);
// Wrong - breaks the URL structure
url += "?q=" + encodeURI(userInput);
If a user types & into a search box and you used encodeURI, the & stays literal and the query string splits in the wrong place. encodeURIComponent escapes it to %26 and the parameter stays intact.
The unreserved characters
RFC 3986 defines these as safe in any context:
A-Z a-z 0-9 - _ . ~ ! * ' ( )
Everything else gets escaped by encodeURIComponent.
The + gotcha
In a query string, a space can be written as %20 or +. In a path, only %20 is valid — + is a literal plus sign there. URLSearchParams encodes spaces as +, which is why new URLSearchParams({q: "a b"}).toString() gives q=a+b.
const p = new URLSearchParams({ q: "a b", tag: "c&d" });
// q=a+b&tag=c%26d
Common errors this fixes
%followed by non-hex — the result is a malformed URL that many servers reject- Unescaped
&in a parameter value — extra parameters appear out of nowhere - Unescaped
#in a value — everything after it is treated as a fragment and lost - Raw spaces in a URL — most browsers auto-escape them, but not every context does
Related
Encoding a whole payload rather than a URL? The Base64 encoder handles binary data safely.
常见问题
Is my text uploaded anywhere?
No. Encoding and decoding both run in your browser using the built-in URL APIs. Nothing is transmitted.
Should I use encodeURI or encodeURIComponent?
Use encodeURI for a complete URL and encodeURIComponent for a single value going into one. The difference is that encodeURI leaves reserved characters like &, ? and / intact.
Why is my space encoded as a plus sign?
In a query string, + is a valid way to encode a space and is what URLSearchParams produces. In a path segment, only %20 is valid — + there is a literal plus sign.
Why does decoding fail on some input?
A % must be followed by two hex digits. If a string contains a bare % or an invalid escape, it is malformed and cannot be decoded.
Can this handle non-ASCII text?
Yes. Characters outside ASCII are encoded as UTF-8 bytes first, then each byte is percent-escaped, so accented characters and emoji survive a round trip correctly.