3Q工具箱
首页 / 教程中心 / 开发辅助

Base64、URL 编码、HTML 实体:三种编码分别解决什么问题

开发辅助发布于 2026-09-06

Base64、URL 编码、HTML 实体这三样经常被混着叫「编码」,但它们解决的是完全不同的问题。用错的典型症状是:链接里的中文变乱码、参数里的加号消失、页面上显示出一串 <div>

先记住一句话:这三种都不是加密,都能被任何人一键还原

一、Base64:让二进制能走文本通道

Base64 把任意字节流用 64 个安全字符(A–Z、a–z、0–9、+/)表示,末尾用 = 补齐。它的用途是让二进制数据能安全地通过只允许文本的通道,比如:

  • 邮件附件(MIME 的历史需求);
  • HTML 里内嵌小图标 data:image/png;base64,...
  • JSON 字段里塞一小段二进制;
  • JWT 的三段结构就是 Base64URL 编码的。

**代价是体积增加约 33%**。每 3 个字节变成 4 个字符,所以只适合小文件。把几 MB 的图片转成 Base64 内嵌进 CSS,会让首屏体积暴涨且无法单独缓存,通常是错误的优化。

Base64URL 变体:标准 Base64 里的 +/ 在 URL 中有特殊含义,所以 URL 场景用 -_ 替代,并去掉末尾的 =。JWT、OAuth 里看到的就是这种。解码时如果报错,先检查是不是把两种变体搞混了,可以在 Base64 编码工具里切换处理。

中文怎么办:Base64 处理的是字节,不是字符。中文必须先按 UTF-8 转成字节再编码,否则不同环境结果不一致。这也是「同一段中文在两个系统 Base64 出来不一样」的原因——一边按 UTF-8,一边按 GBK。

二、URL 编码:让特殊字符能进地址栏

URL 里有一批字符是有语法含义的:? & = # / : + 空格。要把它们当普通数据传输,就得转义成 %XX 形式(百分号加十六进制字节值)。中文按 UTF-8 编码后每个汉字变成 3 个 %XX,所以 %E4%B8%AD 就是「中」。

encodeURI 还是 encodeURIComponent,这是最常问的:

  • encodeURIComponent 编码更彻底,会转义 ? & = # /用来编码单个参数值。
  • encodeURI 保留 URL 结构字符,不转义 ? & = # /用来编码整条完整 URL。

判断方法:你手上的字符串是「一个值」还是「一条链接」。给参数值用前者,是最常见的需求。如果用 encodeURI 编码参数值,值里的 & 不会被转义,后端会把它当成参数分隔符,参数就被截断了——这也是一类真实的注入风险。

加号那个坑。表单默认的 application/x-www-form-urlencoded 格式把空格编码成 +,而 URL 路径里的 + 是字面加号。于是:

提交 "a+b",如果被当作表单编码解析,后端收到 "a b"
提交 "a b",如果被当作路径解析,收到的 %20 才是空格

密码、签名、Base64 字符串里带 + 时特别容易翻车。稳妥做法是把 + 显式编码成 %2B

别重复编码。已经编码过的字符串再编码一次,% 会变成 %25,于是出现 %2520。前后端各编码一次是常见事故,特征是链接里出现 %25

三、HTML 实体:让内容不被当成标签

< 变成 &lt;> 变成 &gt;& 变成 &amp;" 变成 &quot;,作用是让这些字符在页面上显示为字符本身,而不是被浏览器当作标签或属性边界解析。

这件事的重要性在于安全:把用户输入的内容不做转义直接拼进 HTML,对方写一段 <script> 就能在别人浏览器里执行,这就是 XSS。

工程上的正确做法不是「手动调 HTML 实体编解码工具」,而是:

  • 用框架的文本绑定(Vue 的 {{ }}、React 的 {}),它们默认转义;
  • 避开 v-htmlinnerHTMLdangerouslySetInnerHTML,非用不可时先做白名单清洗;
  • 注意上下文不同转义规则也不同:放进属性、放进 <script>、放进 URL 参数各有各的转义方式,光转义 <> 不够。

手动工具的价值在排查:页面上显示出了 &lt;div&gt; 说明被转义了两次,看到标签被真的渲染了说明该转义的地方漏了。

四、Unicode 转义:\u4e2d 是怎么来的

\uXXXX 是把字符写成码点的十六进制形式,常见于 JSON 输出、Java properties 文件、代码里避免非 ASCII 字符。用 Unicode 编解码可以双向转换。

要注意的是代理对:超出基本平面的字符(emoji、部分生僻字)码点大于 U+FFFF,在 UTF-16 里用两个 \uXXXX 表示。所以按「4 个十六进制一组」硬拆会拆坏 emoji,字符串长度统计也会出现「一个 emoji 算两个字符」的现象。

五、编码不是加密

三者都是可逆的公开变换,任何人都能还原。这意味着:

  • Base64 后的密码等于明文密码,只是不便直接肉眼读;
  • 前端把参数 Base64 一下不构成任何安全措施;
  • URL 里的敏感信息即使编码过,也会被浏览器历史、服务器日志、代理完整记录。

真正需要保密的内容要用加密(有密钥、不可逆推),本站的文本口令加密解密走的是 AES-GCM 加口令派生密钥,这才是「别人拿到密文也读不出内容」。

常见问题

Base64 解码报错怎么办? 先看长度是不是 4 的倍数(缺 = 补齐)、是不是混了 Base64URL 的 - _、有没有在复制过程中被插入换行或空格。

为什么后端收到的中文是乱码? 两边编码不一致。确认整条链路统一 UTF-8:页面 charset、请求头 Content-Type 里的 charset、后端解码方式、数据库字符集。任一环节是 GBK 就会乱。

URL 长度有限制吗? 标准没规定,但浏览器和服务器有实际上限(常见 2KB 到 8KB)。中文经 URL 编码后膨胀 3 倍,用 GET 传长文本很容易超限,应该改用 POST。

Base64 能压缩数据吗? 恰好相反,会变大约三分之一。需要减小体积应该先压缩(gzip、zip)再按需 Base64。

这些转换会上传内容吗? 不会。编解码全部在浏览器本地完成,token、密钥、业务数据不会离开你的设备。

文中用到的工具

同类教程