URL 编码与解码
粘贴一段 % 编码的文本,或者它背后的原文,双向都能转。粘贴即出结果,没有按钮。+ 的含义和严格 RFC 3986 字符集都是开关 —— 因为这两件事猜错一个,产出的字符串就是错的,而且看起来还挺像对的。
什么都能粘:完整 URL、查询串、已编码的文本,或者你想编码的原文。
什么时候会用到
- 一个查询参数被编码了两次,你想看清它到底写了什么。
- 你在拼签名或跳转 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,页面加载过一次之后断网也能继续用。