Base64URL 只替换两个字母表字符:标准版的加号变成连字符,斜杠变成下划线。信息没有变化。它适合外层协议会特殊处理加号或斜杠的场景,但不能因此忽略其他 URL 与应用规则。
使用能体现差异的样本
FB FF 两个字节的标准编码为 +/8=,URL-safe 编码为 -_8=。Hello 之类样本可能只产生两种字母表共有的字符,无法判断选项是否有效。
const standard = btoa(String.fromCharCode(251, 255));
const urlSafe = standard.replace(/\+/g, '-').replace(/\//g, '_');
console.log(standard); // +/8=
console.log(urlSafe); // -_8=
填充是另一项约定
许多令牌格式省略末尾等号,另一些系统保留。替换字母表与移除填充是不同选项。无填充长度除以四余二时,需要补两个等号;余三补一个;余一无法仅靠填充修复,因为一个六位字符不足以表示完整字节。
校验时还要检查最后字符的未使用位。忽略它们的解码器可能接受多个字符串表示同一字节,在直接比较编码字符串时产生歧义。规范编码应输出统一形式。
区分查询解析与 Base64 解码
表单式查询参数解析会把字面加号变成空格。标准 Base64 未转义就放入查询参数,可能在解码前已损坏。应使用 URLSearchParams 构建参数,或按接收协议选择 Base64URL。
const query = new URLSearchParams({ payload: '+/8=' });
console.log(query.toString()); // payload=%2B%2F8%3D
console.log(query.get('payload')); // +/8=
不要自动把全部空格替换成加号:空格可能来自真实格式或另一类错误。先保存原文,定位改变数据的传输层,再明确修正。JWT 应使用其格式规定的规则。字母表定义见 RFC 4648,填充、空白和长度限制仍由具体集成决定。