UTF-8 把字符映射成字节,Base64 把字节映射成受限文本,URL 百分号编码保护 URI 组件。它们位于不同层次,不是可以互换的样式。
许多 API 问题来自把正确算法用错层:对 Unicode 直接 btoa、把整个 URL 当单个组件编码,或把可逆表示当作加密。
分层模型
JavaScript 字符串表示 Unicode。TextEncoder 生成 UTF-8 字节,Base64 再把字节表示为 ASCII;该值进入查询参数时还可能需要百分号编码。
顺序很重要。“你好”要先变成 UTF-8 字节再做 Base64;标准 Base64 的加号、斜杠和等号进入 URL 时可能仍需转义。
Unicode 文本 -> UTF-8 字节 -> Base64 文本 -> URL 组件每种机制的职责
UTF-8 用于文本互操作,Base64 让任意字节进入纯文本通道,百分号编码保护 URI 语法,Unicode 转义是源码表示,HTML 实体属于 HTML 解析上下文。
它们都不提供保密性,只解决表示和语法问题。
| 机制 | 输入 | 输出 | 用途 |
|---|---|---|---|
| UTF-8 | Unicode 文本 | 字节 | 文本互操作 |
| Base64 | 字节 | ASCII 文本 | 二进制进文本 |
| 百分号编码 | URL 组件 | %HH | URI 安全 |
| Unicode 转义 | Code point/unit | \uXXXX | 源码表示 |
| HTML 实体 | HTML 字符 | &name; | HTML 上下文 |
Base64 不是字符集
Base64 只处理字节。文本应先经 TextEncoder,Base64 解码后的字节再由 TextDecoder 恢复。
btoa 假设输入是类似 Latin-1 的单字节字符,非 ASCII 可能失败;字节优先实现能避开问题。
URL 上下文很重要
encodeURIComponent 用于单个路径或查询组件,encodeURI 保留完整 URL 分隔符。对完整 URL 使用 encodeURIComponent 会破坏结构。
表单查询中加号可以表示空格,URLSearchParams 能按规则序列化,避免手工替换。
Base64URL 仍不是加密
Base64URL 替换加号和斜杠,并常省略 padding;JWT 使用 Base64URL 分段。
JWT Header 与 Payload 通常任何人都能解码,签名验证是另一回事。
选择规则
按接收接口选择:支持二进制就直接发送,纯文本字段明确要求才用 Base64,URL 组件做百分号编码,文本边界使用 UTF-8。
- 文本转字节:UTF-8。
- 字节进文本字段:Base64。
- 查询值:URLSearchParams。
- JWT:Base64URL 加签名验证。
- HTML:按 HTML 上下文转义。
总结
按层次选择:UTF-8 定义文本字节,Base64 把字节变成受限文本,百分号编码保护 URI 组件,才能避免 Unicode 损坏、链接失效和虚假安全感。