URL 编码解释:百分比编码、encodeURI 与encodeURIComponent 以及 %2520 Bug

2026年7月11日 · 7 分钟阅读

每个使用用户输入构建 URL 的开发人员都遇到过这样的情况:带有空格或与号的搜索词会破坏链接,突然一半的查询在服务器上丢失。修复方法是 URL 编码,也称为百分比编码,但它带有两个很容易混淆的函数,以及一个在链接中产生令人困惑的 %2520 的错误。本指南清除了所有这些。

为什么 URL 需要编码

URL 只允许包含由 RFC 3986 标准定义的有限字符集。该字符集基本上是非保留字符、字母、数字和一些符号(例如连字符和下划线),以及一些具有特殊结构含义的保留字符,例如?开始查询,& 分隔参数,= 将键与值配对,/ 表示路径段,# 表示片段。该集合之外的任何内容(空格、重音字母、表情符号或用作数据而不是结构的保留符号)都必须进行编码,否则 URL 就会中断。

百分比编码通过用百分号后跟其两位十六进制字节值替换不安全字符来实现此目的。空格变为%20。 & 符号变为 %26。 at 符号变为 %40。在另一端,服务器将这些解码回原始字符。整个系统的存在使得任意文本都可以嵌入 URL 的严格结构中,而不会被误认为是该结构的一部分。

核心问题:数据与结构

这是导致大多数错误的情况。想象一下搜索文字文本“cats & dogs”。如果您将其直接放入查询字符串中,如 q=cats & dogs,则 & 将被读取为参数分隔符,服务器会看到参数 q=cats 和第二个无意义的参数 dogs,并且您的搜索将被破坏。空间也会带来麻烦。 & 符号需要变为 %26 和空格 %20,以便服务器了解它们是值的一部分,而不是 URL 结构的一部分。编码就是你所说的“这个字符是数据,而不是分隔符”。

编码 URI 与 编码 URI 组件

JavaScript 为您提供了两种编码函数,选择错误的一种是最常见的 URL 错误之一。区别在于他们认为“安全”并且不去管。

encodeURIComponent 对保留的所有内容进行编码,包括 / ? & = # 等等。它用于对插入到 URL 中的单个值、查询参数值、搜索词、重定向目标进行编码。将其用于碎片。相比之下,encodeURI 故意保留 URL 结构字符 (/ ? & =),因为它的目的是对整个已组装的 URL 进行编码,同时保持其功能。将其用于整个事情,很少。

经验法则:如果要对 URL 内部的值进行编码,请使用encodeURIComponent。如果您正在对完整的 URL 进行编码,并且只想修复杂乱的非法字符而不破坏其结构,请使用encodeURI。当有疑问时,您几乎总是需要encodeURIComponent,因为您几乎总是对一个值进行编码。

错误选择示例:在重定向参数上使用encodeURI 会使重定向自己的查询字符串中的& 和= 未编码,因此外部URL 会误读它们。该值上的encodeURIComponent 将它们编码为%26 和%3D,保持值不变。

%2520 bug:双重编码

这个第一次让大家感到困惑。您在预期为 %20 的 URL 中看到 %2520,并且链接已损坏。发生的事情是这样的:已经编码的字符串被第二次编码。第一个编码将空格转换为 %20。然后第二个编码对百分号本身进行编码,% 变成 %25,将 %20 变成 %2520。现在服务器将其解码为%20(字面意思是文本“%20”)而不是空格,并且下游的所有内容都是错误的。

原因几乎总是对已经编码的值进行编码,例如,从已经进行 URL 编码的字符串构建 URL,然后再次通过编码器运行它。避免这种情况的规则是:只对原始的、未编码的文本进行编码。切勿对已编码的 URL 或值进行编码。如果不确定字符串是否已编码,请先对其进行解码,然后再对其进行一次编码。

加号歧义

又一个陷阱。在查询字符串中,加号 (+) 有时被解释为空格,这是旧版 HTML 表单编码 application/x-www-form-urlencoded 的遗留问题。但在 URL 路径中,+ 是字面加号。这种不一致意味着数据中的 + 在一个地方可以被读取为空格,而在另一个地方可以被读取为加号。安全的做法是始终将空格编码为 %20,这在任何地方都是明确的,而不是依赖于 +。如果你看到空格变成了优点,反之亦然,这种模糊性通常就是罪魁祸首。

实用的外卖

对放入 URL 中的值进行编码,对这些值使用encodeURIComponent,仅对原始文本进行编码以避免 %2520 双重编码错误,并且对于空格优先使用 %20 而不是 +。当您需要手动构建或检查 URL 时,快速编码器和解码器可以让您准确地看到字符串变成了什么,并在发布之前捕获这些问题。

TextCaret URL 编码/解码工具按照encodeURIComponent 的方式对文本进行百分比编码,因此您可以安全地准备查询值或解码神秘的 %2520 以查看出了什么问题,所有这些都在您的浏览器中进行。