URL 编码与解码

粘贴一段 % 编码的文本,或者它背后的原文,双向都能转。粘贴即出结果,没有按钮。+ 的含义和严格 RFC 3986 字符集都是开关 —— 因为这两件事猜错一个,产出的字符串就是错的,而且看起来还挺像对的。

什么都能粘:完整 URL、查询串、已编码的文本,或者你想编码的原文。

URL 选项 —— 只改“怎么转”

表单编码用 + 表示空格,这与 %20 不是一回事 —— 所以它下面单独有一个开关。

RFC 3986 会编码 encodeURIComponent 放过的五个字符。把 URL 放进另一个 URL、或做签名规范化时要用它。

处理 application/x-www-form-urlencoded 的内容时打开(表单、查询串)。+ 本身就是数据时请关闭。

什么时候会用到

  • 一个查询参数被编码了两次,你想看清它到底写了什么。
  • 你在拼签名或跳转 URL,而 +%20 的区别决定它能不能通过校验。
  • 日志里是一段百分号编码的内容,你想看到可读形式,又不想为此写个一次性脚本。

别的 URL 编码工具为什么在这里出错

多数工具用 decodeURIComponent 解一次就完事,于是 + 保持为字面加号。这对路径是对的,对查询串是错的 —— 而工具从不问你是哪一种。

几乎没有工具提供严格的 RFC 3986 字符集。encodeURIComponent 出于历史原因不转义 !'()*,这会破坏签名和嵌套 URL。

遇到坏的 % 时它们只说一句 URI malformed:不给位置、不给字符,也不提示这段字符串可能是在转义中途被截断的。

允许静默地对已经编码过的值再编码一次,于是 % 变成 %25,结果错得很像是对的。

常见问题

空格到底该用 + 还是 %20

取决于这段字符串要去哪里 —— 所以它做成开关而不是默认值。在 application/x-www-form-urlencoded 的查询部分(HTML 表单提交、多数服务端框架的查询解析器),空格写作 +,解码时就要把 + 还原成空格。而在路径段、片段,或用 encodeURIComponent 生成的参数值里,空格是 %20+ 就是字面加号。开关开错了会把真实的加号静默替换成空格。

严格字符集到底改了什么?

恰好五个字符:!'()*。标准 encodeURIComponent 会原样保留它们,因为早期网页代码依赖这个行为。而 RFC 3986 把它们视为保留字符,所以当 URL 要嵌进另一个 URL、或者要参与签名/HMAC 计算时,必须把它们百分号编码。如果你产出的签名对方一直校验不过、而解码后的值看起来一模一样,原因通常就在这里。

为什么结果里还有百分号?

说明这个值被编码了不止一次 —— 参数先被编码、整个 URL 又被编码一遍时很常见。工具会报出结果里还剩多少处 %XX,让你知道还需要再解一次。再解一次能得到原文,但请核对结果:多解一次会把本来就想当字面量的 % 也一起解掉。

它说我的 % 不合法,什么才算合法?

百分号后面必须紧跟两位十六进制数字。%20%E4%2f 合法;%%2%ZZ 不合法。工具会告诉你第一个坏转义的位置以及总共有几处 —— 因为这几乎总是截断或手工改过,而不是什么微妙的问题:一个值在转义中途被截断,第二个十六进制位就没了。

转义看着挺好,却报 UTF-8 非法。

百分号编码作用于字节,而工具要求这些字节是合法的 UTF-8。%E4%F8 会失败,因为 F8 不能作为 UTF-8 序列的首字节。实践中这通常意味着这段文本在转义之前用的是 Latin-1、GBK 之类的旧字符集。面板会把出问题的字节按十六进制列出来,便于判断是哪种编码产生的。

我输入的内容会被发到别处吗?

不会。转换就在这个页面里用纯字符串操作完成,也没有后端可以接收它。打开 DevTools 的 Network 面板,随便转一次:不会发出任何请求。本站可安装为 PWA,页面加载过一次之后断网也能继续用。

其它工具