跳到正文

URL解码

把%E2%9C%93还原为✓。双重编码的字符串、表单编码和残缺的输入都能处理,而不是直接拒绝。不存储任何内容。

  • 绝不存储
  • 无需排队,无需等待
  • 无需注册,无水印
解码结果

解码结果将显示在这里。

使用方法

1

粘贴编码后的文本

完整的URL、查询字符串,或者只是单个值。

2

按需选择解码方式

标准解码,或把+当作空格的表单解码。如果不确定,两种结果不同时页面会提示您。

3

复制结果

如果文本被编码了两次,就再解码一次——这种情况很常见,一旦看到就很容易识别。

没有任何工具能替您消除的歧义

解码在机制上很简单——找到每个后面跟着两位十六进制数字的%,把它还原成一个字节,再把这些字节按UTF-8读取——而其中恰好只有一处真正的歧义。加号可能表示空格,也可能就是加号。在提交的表单中它表示空格,这个约定比网络自身的URL规范还要古老。在路径片段中,它是字面字符。文本本身没有任何信息说明适用哪一种,所以页面会把两种解读都展示给您,而不是挑一种然后悄悄出错——这在最容易出问题的场景中最为重要:邮箱地址或Base64值里的加号是真实数据。

非ASCII文本中的每个字符都会变成好几段百分号序列,因为编码针对的是UTF-8字节,而不是字符:一个带重音的字母是两段,大多数符号是三段,一个emoji是四段。解码一段不是有效UTF-8的序列,就会得到替换字符——这通常说明文本是用另一种字符集编码的,或者在某个字符中间被截断了。

重复解码是安全漏洞,而不只是失误。如果一个值先被解码、再被校验、然后又被解码一次,攻击者就能让某些字符躲过校验:%252e%252e%252f能通过查找“../”的过滤器,因为解码一次后它仍是%2e%2e%2f,而第二次解码后,它就变成了过滤器本该拦截的路径穿越。只解码一次,然后校验,顺序绝不能反过来。

从未编码过的文本会原样返回,不会被弄乱——当您不确定一个字符串到底需不需要解码时,这正是有用的行为。后面没有跟着两位十六进制数字的百分号会保持不变,不会被当作错误——那是字面意义上的百分号,常见于直接粘贴而非经过编码的文本。

如果您需要的是别的

在代码中,解码器应该与编码器配套。JavaScript有decodeURIComponent;Python恰恰因为加号问题而区分了unquote和unquote_plus;PHP出于同样的原因提供rawurldecode和urldecode。更好的做法是交给URL类型或查询字符串解析器处理——大多数框架会替您解码参数,而之后再解码一次,正是上文所说的重复解码漏洞的由来。

如果是要查看一个很长的URL,而不是解码某个值,解析器比解码器更合适:python -c "import urllib.parse,sys; print(urllib.parse.urlparse(sys.argv[1]))"会把地址拆分成各个组成部分,让您在解码之前先看清哪一段是哪一段——链接出问题时,这通常才是真正要弄清的事。

常见问题

解码后文本里还有%25

说明它被编码了两次,这极其常见——每当一个已编码的值在经过重定向或日志层时又被编码一次,就会出现这种情况。%25是%字符本身的编码,所以第一次解码把%2520变成%20,第二次解码再把它变成空格。再解码一次即可。页面发现这种情况时会提示您。

“+”应该变成空格吗?

取决于字符串的来源,所以这是一个选项,而不是猜测。在application/x-www-form-urlencoded请求体中——也就是提交的HTML表单——+表示空格。在路径片段中,或者在只是经由URL传递的数据中,+是字面意义上的加号,把它变成空格会破坏这个值。最容易踩坑的是Base64字符串:它们包含真实的+字符,用表单方式解码就会把它毁掉。

字符串有损坏会怎样?

能解码的部分会被解码,其余部分保持原样,而不是全部拒绝。一个不属于有效转义序列的孤立%——在文本已被部分解码或被截断时很常见——会让浏览器自带的解码器抛出错误,什么都不返回。在这里,每个有效的转义序列都会被解码,孤立的字符原样保留,当您想读懂一行损坏的日志时,这要有用得多。

我的文本会被存储吗?

不会。不存储任何内容,也不发出任何请求。页面加载完成后,即使断开网络也照样能用。

能一次解码整个URL吗?

能。把整个URL粘贴进来——结构保持可读,只有编码的部分会被还原为文本,所以一个带有多个编码参数的长URL会变得真正可以读懂。

小贴士: 加号存在歧义:在查询字符串中它表示空格,在路径中则是字面意义上的加号。页面会按两种方式分别解码,并标明哪个是哪个,而不是去猜。从未经过百分号编码的文本会原样返回,不会被弄乱。

把这个工具放到您的网站上

博客、课程页面或帮助文章均可免费使用。粘贴一段代码,访客就能直接在您的页面上使用。