URL 编码:组件 vs 完整,以及中间的保留字符
为什么 encodeURIComponent 与 encodeURI 产生不同输出、哪些字符在哪个位置是保留的,以及如何为查询值、路径与片段选择正确的模式。
问题
为什么 encodeURIComponent 与 encodeURI 产生不同输出、哪些字符在哪个位置是保留的,以及如何为查询值、路径与片段选择正确的模式。
步骤
-
1. Percent-encoding in one paragraph
URLs allow a fixed set of characters. Anything outside the allowed set is written as % followed by the byte's two hex digits: a space becomes %20, '=' becomes %3D. The subtlety is that 'allowed' depends on position: the characters that separate URL parts (?, &, =, /, ;) are legal inside a URL but must be encoded when they appear inside a value. Percent-encoding has exactly one rule — encode enough that the value cannot be mistaken for structure — and the two classic functions differ in how much 'enough' means.
-
2. encodeURIComponent vs encodeURI
encodeURIComponent escapes everything except unreserved characters (A–Z a–z 0–9 - _ . ! ~ * ' ( )), which makes it correct for single values: query parameters, path segments, cookie values. encodeURI is for whole URLs: it deliberately preserves the structural characters (? / & = : ; @ + $ , #) because a complete URL needs them. The recurring bug is using encodeURI on a value — the & and = inside it then merge with the URL's own structure and the server reads two parameters instead of one.
-
3. The space question: %20 vs +
In the application/x-www-form-urlencoded format (HTML form posts, most frameworks' query parsers), a space is encoded as '+'. In the URI standard itself (RFC 3986), a space is %20 and '+' is a literal plus. Both conventions coexist: a value containing a real plus sign must be encoded as %2B in form-style query strings or it will be decoded back to a space. When interoperability matters, prefer %20 and treat '+' in received values according to the sender's documented convention.
-
4. Double encoding and the debugging habit
The most common encoding bug is encoding twice: %2520 (the % itself encoded) appears when a framework escapes a value that was already a string containing escapes. The symptom is a parameter that decodes to something still-looking-encoded. Debug by decoding once at a time and checking the result at every layer — a chain like URL-decode → Base64-decode → JSON format mirrors how multi-layer API parameters are actually built.
预期结果
You can choose between encodeURIComponent and encodeURI based on which characters are reserved in each position, resolve the %20 vs + question, and debug double encoding by decoding one layer at a time.