URL编码与解码

对URL和查询字符串中的文本进行百分号编码,或将%20这类已编码的URL解码为可读文本。

100% 在浏览器中运行。粘贴的内容不会被上传或存储。
文本或已编码的URL
结果
就绪。

如何使用 URL 编码与解码工具

  1. 选择编码或解码。
  2. 选择一种模式:组件用于单个查询值或路径段,完整 URL 则保持 URL 的结构(:、/、?、&)不变。
  3. 粘贴文本或 URL,并复制结果。

一切都在浏览器中处理。URL 的查询字符串中常常带有令牌和个人数据,这些内容都不会被上传或存储。

什么是百分号编码?

URL 只能包含有限的一组 ASCII 字符。RFC 3986 定义的百分号编码,把任何其他字节表示为一个百分号后跟两位十六进制数字。文本先被转换为 UTF-8 字节,然后每个需要转义的字节写成 %XX:

café & crème   →   caf%C3%A9%20%26%20cr%C3%A8me

这里 é 是两个 UTF-8 字节(C3 A9),空格变成 %20,和号变成 %26。

保留字符与非保留字符

分组字符含义
非保留字符A–Z a–z 0–9 - . _ ~从不需要编码。
保留字符:gen-delims: / ? # [ ] @分隔 URL 的主要部分。
保留字符:sub-delims! $ & ' ( ) * + , ; =分隔某一部分内的数据,例如查询字符串中的 & 和 =。

当保留字符作为数据而不是分隔符出现时,必须对其编码。搜索 R&D 时必须发送为 q=R%26D;否则服务器会看到名为 D 的第二个参数。

encodeURIComponent 与 encodeURI

JavaScript 提供了两个函数,选错其中一个是导致缺陷的常见原因:

  • encodeURIComponent() 会对除 A–Z a–z 0–9 - _ . ! ~ * ' ( ) 之外的所有字符编码。把它用于单个值:查询参数、路径段、片段数据。
  • encodeURI() 还会保留 ; , / ? : @ & = + $ # 不变,因此可以应用于完整的 URL而不破坏其结构。它无法保护包含 & 或 # 的值。
encodeURI("https://example.com/a b?q=R&D")
// "https://example.com/a%20b?q=R&D"      (& left alone)

"https://example.com/search?q=" + encodeURIComponent("R&D")
// "https://example.com/search?q=R%26D"

更好的办法是让 URLSearchParams 或所用编程语言的 URL 库来构建查询字符串。

常见陷阱

+ 与 %20

以 application/x-www-form-urlencoded 提交的 HTML 表单会把空格编码为 +。而在 RFC 3986 的 URL 中,+ 是字面的加号,空格是 %20。不知道使用了哪种约定的解码器,可能会把 C++ 变成 C ,或者把本该是空格的位置留下 +。为稳妥起见,请把真正的加号编码为 %2B。

Python:  urllib.parse.quote("a b&c")       → a%20b%26c
         urllib.parse.quote_plus("a b&c")  → a+b%26c

重复编码

对已编码的字符串再次编码,会转义百分号本身:%20 变成 %2520。这通常发生在某个值先被您的代码编码、又被框架或 HTTP 客户端再编码一次的时候。如果在 URL 中看到 %25,就要怀疑是重复编码。解码两次同样有害:它可能把用户数据中字面的 %41 变成 A。

把整个 URL 当作组件来编码

对完整 URL 运行 encodeURIComponent 会转义 :// 和每一个 /,得到 https%3A%2F%2F...。只有当该 URL 本身是某个参数的值(例如 redirect_uri)时,这样做才是正确的。

小提示

  • 百分号编码中的十六进制数字不区分大小写,但 RFC 3986 推荐使用大写(%2F,而不是 %2f)。
  • 国际化域名不使用百分号编码;它们改用 Punycode(xn--)。
  • 需要在 URL 中传输二进制数据?URL 安全的 Base64 比对每个字节做百分号编码更紧凑。
  • 用 HTTP响应头检测查看服务器如何处理您编码后的请求。

常见问题

为什么空格有时是 +,有时是 %20?

+ 来自查询字符串和 POST 请求体中使用的 HTML 表单编码;%20 则是 RFC 3986 的通用编码,在 URL 的任何位置都有效。拿不准时,请使用 %20。

哪些字符从不需要编码?

非保留字符集:字母、数字、连字符、句点、下划线和波浪号。其他所有字符,只要是值的一部分,都应当编码。

URL 编码是一种安全措施吗?

不是。它只是让数据在 URL 内部语法上安全,并且完全可逆。它本身既不能隐藏数据,也不能防止注入。

如何解码带有 %uXXXX 序列的 URL?

%uXXXX 是已弃用的 JavaScript escape() 函数产生的非标准格式。标准解码器会拒绝它;必须另行转换。

更新于

已复制到剪贴板