Text parsing ·
URL encoding and percent-encoding variants in web app security
Percent-encoding is not one function. RFC 3986 defines a reserved set. encodeURI leaves :/?#[]@ intact. encodeURIComponent encodes them. HTML forms turn space into +. Mixing these is how query parsers split on the wrong ampersand and how open redirects slip through allowlists.
RFC 3986 reserved set
gen-delims and sub-delims. Encoding a slash in a path vs a query value means different things. Decode once at the boundary; do not ping-pong.
The three JS APIs
encodeURI, encodeURIComponent, URLSearchParams. The last is the right default for query maps. url-encoder-decoder shows the others for debugging.
Plus versus %20
Space in path should be %20. In forms, +. Search engines and log parsers disagree. Be explicit in APIs you design.
Double-encoding and open redirects
%252e%252e%252f sequences bypass naive filters. Decode iteratively with a cap. Tokens in query strings (JWT article) should not be decoded as paths.
IDNA
Hostnames use punycode, not percent-encoding of Unicode the same way paths do. URL parser tools should show both href and hostname.
Frequently asked questions
When do I use encodeURI versus encodeURIComponent?
encodeURI for a full URL you already structured. encodeURIComponent for a single path segment or query value. Never encodeURIComponent a whole URL unless you intend to embed it as a value.
Why is + a space in forms?
application/x-www-form-urlencoded historically uses +. URLSearchParams follows that. Path encoding does not.
Can percent-encoding stop XSS?
It is the wrong layer. HTML context needs entity encoding. URL context needs percent-encoding. Confusing them is a bug.