完整的 URL 编码字符对照表(ASCII + Unicode)
URL 编码字符的完整参考对照表。涵盖所有 ASCII 可打印字符(32-126)、常见 Unicode 字符,以及它们按照 RFC 3986 定义的百分号编码形式。
ASCII 控制字符与特殊字符
ASCII 编码在 0-31 范围内的字符以及第 127 号字符属于控制字符。它们不可打印,在 URL 中必须始终进行百分号编码。在 URL 场景中最常遇到的控制字符包括空格(ASCII 32)、水平制表符(ASCII 9)以及换行符(ASCII 10 和 13)。
根据 RFC 3986,凡是既不属于非保留字符、也不是用于其保留用途的保留字符、且不是百分号编码三元组的任何字节,都必须进行百分号编码。在实践中,这意味着 URI 组件中的大多数非字母数字字符都应当被编码。
| 字符 | ASCII 码 | URL 编码 | 说明 |
|---|---|---|---|
| (tab) | 9 | %09 |
水平制表符 |
| (LF) | 10 | %0A |
换行符 |
| (CR) | 13 | %0D |
回车符 |
| (space) | 32 | %20 |
空格 |
可打印 ASCII 字符
下面是所有可打印 ASCII 字符(编码 32-126)及其 URL 编码形式的完整参考。在 RFC 3986 中被标记为“非保留(unreserved)”的字符无需编码。保留字符在其保留用途之外使用时必须编码。
| 字符 | ASCII | 十六进制 | URL 编码 | 类型 |
|---|---|---|---|---|
| (space) | 32 | 20 | %20 |
特殊 |
| ! | 33 | 21 | %21 |
保留 |
| " | 34 | 22 | %22 |
不安全 |
| # | 35 | 23 | %23 |
保留 |
| $ | 36 | 24 | %24 |
保留 |
| % | 37 | 25 | %25 |
特殊 |
| & | 38 | 26 | %26 |
保留 |
| ' | 39 | 27 | %27 |
保留 |
| ( | 40 | 28 | %28 |
保留 |
| ) | 41 | 29 | %29 |
保留 |
| * | 42 | 2A | %2A |
保留 |
| + | 43 | 2B | %2B |
保留 |
| , | 44 | 2C | %2C |
保留 |
| - | 45 | 2D | %2D |
非保留 |
| . | 46 | 2E | %2E |
非保留 |
| / | 47 | 2F | %2F |
保留 |
| 0-9 | 48-57 | 30-39 | 无需编码 | 非保留 |
| : | 58 | 3A | %3A |
保留 |
| ; | 59 | 3B | %3B |
保留 |
| < | 60 | 3C | %3C |
不安全 |
| = | 61 | 3D | %3D |
保留 |
| > | 62 | 3E | %3E |
不安全 |
| ? | 63 | 3F | %3F |
保留 |
| @ | 64 | 40 | %40 |
保留 |
| A-Z | 65-90 | 41-5A | 无需编码 | 非保留 |
| [ | 91 | 5B | %5B |
保留 |
| \ | 92 | 5C | %5C |
不安全 |
| ] | 93 | 5D | %5D |
保留 |
| ^ | 94 | 5E | %5E |
不安全 |
| _ | 95 | 5F | %5F |
非保留 |
| ` | 96 | 60 | %60 |
不安全 |
| a-z | 97-122 | 61-7A | 无需编码 | 非保留 |
| { | 123 | 7B | %7B |
不安全 |
| | | 124 | 7C | %7C |
不安全 |
| } | 125 | 7D | %7D |
不安全 |
| ~ | 126 | 7E | %7E |
非保留 |
常见 Unicode 编码
Unicode 字符首先会被编码为其 UTF-8 字节序列,然后每个字节再单独进行百分号编码。多字节字符会产生多个百分号编码三元组。
| 字符 | 说明 | UTF-8 字节 | URL 编码 |
|---|---|---|---|
| 带分音符的 a | 带分音符的拉丁小写字母 A | C3 A4 | %C3%A4 |
| 带波浪符的 n | 带波浪符的拉丁小写字母 N | C3 B1 | %C3%B1 |
| 带尖音符的 e | 带尖音符的拉丁小写字母 E | C3 A9 | %C3%A9 |
| 带分音符的 u | 带分音符的拉丁小写字母 U | C3 BC | %C3%BC |
| 欧元符号 | 欧元符号 | E2 82 AC | %E2%82%AC |
| 英镑符号 | 英镑符号 | C2 A3 | %C2%A3 |
| 日元符号 | 日元符号 | C2 A5 | %C2%A5 |
| CJK 中 | CJK 统一表意文字(中) | E4 B8 AD | %E4%B8%AD |
| 西里尔字母 Ya | 西里尔大写字母 Ya | D0 AF | %D0%AF |
| 阿拉伯字母 Ba | 阿拉伯字母 Ba | D8 A8 | %D8%A8 |
多字节字符是如何编码的
UTF-8 采用变长编码方案。ASCII 范围内的字符(0-127)使用一个字节;超出该范围的字符使用两到四个字节。在进行百分号编码时,UTF-8 表示中的每个字节都会变成一个独立的 %XX 三元组。
双字节字符(U+0080 至 U+07FF): 这类字符包括大多数拉丁扩展、希腊、西里尔以及阿拉伯字符。例如,德语字母 sharp s(U+00DF)编码为 UTF-8 字节 C3 9F,进而变成 %C3%9F。
三字节字符(U+0800 至 U+FFFF): 这类字符包括 CJK 字符、大多数符号以及基本多文种平面。例如,日语平假名字符(U+3042)编码为 UTF-8 字节 E3 81 82,进而变成 %E3%81%82。
四字节字符(U+10000 至 U+10FFFF): 这类字符包括表情符号(emoji)以及增补字符。例如,咧嘴笑脸表情(U+1F600)编码为 UTF-8 字节 F0 9F 98 80,进而变成 %F0%9F%98%80。
// 多字节编码的 JavaScript 演示
console.log(encodeURIComponent('u with umlaut'));
// 两个字节: "%C3%BC"
console.log(encodeURIComponent('CJK char'));
// 三个字节: "%E4%B8%AD"
console.log(encodeURIComponent('emoji'));
// 四个字节: "%F0%9F%98%80"
// 你可以通过解码来验证
console.log(decodeURIComponent('%C3%BC')); // u with umlaut
console.log(decodeURIComponent('%E4%B8%AD')); // CJK char