第 2 课

百分号编码规则

`%XX` 如何表示字节,以及哪些字符通常需要编码。

百分号编码用 % 加两个十六进制数字(各一位半字节)表示要被转义的 单个字节

字节 32(空格)→ %20
字节 38(&)   → %26
字节 231       → 十六进制 E7 → %E7(语义取决于后续如何解码!)

A–F 不分大小写(%e7%E7 等价)。实现上应尽量风格一致,%XX 大写常用于可读性和差异比对,但解析器理应兼容混用。

一次转义对应一字节(不是 UTF-16 码元)

编码 Unicode 字符串 时,一般先把字符串序列化为 UTF-8 字节,再对每个需要转义的字节写 %HH

符号 π(U+03C0)

UTF-8 字节序列:CF 80 → %CF%80

错误心智:直接用码点写成某种「03C0 的魔法十六进制」
正确心智:先得到字节序列,再按字节做 % 转义

哪些字节通常要考虑转义

教学向的实用清单:

  1. 数据结构意义上属于数据的字节,但它的图形字符会像 URI 标点那样参与解析(?&#/:@[] 等)。
  2. 非 ASCII,为扩大互操作性往往整段稳妥转义路径或查询值中的多字节序列。
  3. 控制字节、空格等作为「字面含义」出现时,也需转义以避免被当作分隔或被中间层改写。

RFC 3986 规定通用语法与规范化建议;个别框架可能还会禁止残缺的 %,或对某些字符施加更严格的策略。

无效转义示例

不完整或非法的组合会让解析失败或产生安全隐患:

%           → 缺少两位十六进制(畸形)
%AB         → 只有一位十六进制(畸形)
%GG         → G 不是合法十六进制数位

健壮的库通常在构造阶段校验,或对畸形输入报错,而不是静默「猜一个字节」。

过度编码与二次编码

重复执行百分号编码是常见陷阱:

原始取值:100%

第一次:  100%25        (字面量 % 变为 %25)
误再编:  100%2525      (把已转义的 % 再次编码)

若网关或框架做 多次解码%2525 可能最终变成单个 %,与展示层预期不符。团队应约定:某一层输入到底是「已编码」还是「已解码」,并保持单一责任。

规范化提示

实现之间常见差异包括:

  • 十六进制字母大小写(两种都合法)。
  • 对于某部件中 法律上可省略转义 的标点,是保留字面还是统一转义。
  • 是否在编码前将 Unicode 规范化为 NFC(可选,可减少「拼写不同但视觉相同」造成的签名或缓存键分裂)。

在 CDN、应用、数据库与日志管道之间保持 一致的编码/解码策略,能显著减少验签失败与缓存命中异常。

想动手练习时,可使用 DevCove 相关工具——可选,不属于本课正文。

打开相关工具

返回课程概览