URL 编解码

把中文、空格、emoji 这类不能直接出现在 URL 里的字符和 %XX 互相转换,并区分「编码一个参数值」和「编码整个网址」两种场景。

输入
输出

      

encodeURIComponent 和 encodeURI 差在哪

encodeURIComponent 会把 / ? : & = # + 这些在 URL 里有特殊含义的字符一起编码,所以它适合编码一个参数值;encodeURI 会放过这些结构字符,只把中文、空格等非法字符编码,所以它适合编码一个完整的网址。判断标准只有一个问题:你手上这段字符串是 URL 的一部分,还是整个 URL?

输入encodeURIComponentencodeURI
a=1&b=2a%3D1%26b%3D2a=1&b=2
中文%E4%B8%AD%E6%96%87%E4%B8%AD%E6%96%87
https://a.com/b?c=dhttps%3A%2F%2Fa.com%2Fb%3Fc%3Ddhttps://a.com/b?c=d

用错方向的后果很直接:把整个网址丢进 encodeURIComponent,https:// 会变成 https%3A%2F%2F,链接直接失效;反过来用 encodeURI 编码一个参数值,值里的 & 不会转义,服务端会把它当成新的参数分隔符,参数被截成两段。

中文、空格和 emoji 编出来是什么样

编码的本质是把字符按 UTF-8 转成字节,再逐字节写成 %XX。一个常用汉字是 3 字节,所以「中」是 %E4%B8%AD;空格 1 字节,是 %20;emoji 处在基本平面之外,占 4 字节,一个 🐟 会变成 %F0%9F%90%9F。看到一长串百分号不用慌,整段粘进解码模式就能还原。

表单模式 application/x-www-form-urlencoded 里空格惯例写成 +(而不是 %20),+ 本身要写成 %2B。编解码都遵守这个约定的场合,勾上「表单模式」即可;勾选后解码会把 + 还原成空格。

四个常见的坑

  1. 百分号要写成 %25。原文里如果有一个裸的 %,解码时会被当成百分号序列的开头,直接报错。
  2. 重复编码。已经编码过的字符串再编一次,%E4%B8%AD 会变成 %25E4%25B8%25AD,页面上就看到「%25E4…」。这类输出多解码一次即可还原。
  3. 参数值里的 # 要编码成 %23。井号在 URL 里是锚点起点,不编码的话它后面的内容不会发给服务端。
  4. 解码报错不一定是工具的问题。遇到单独的 %、%ZZ 或截断的 %E4,decodeURIComponent 一定会抛异常。这里会捕获并指出是第几行,不会给你一个 undefined。

常见问题

为什么不能用 encodeURIComponent 编码整个 URL?
它会把冒号、斜杠、问号、等号、& 全部编码,得到 https%3A%2F%2F...,这串东西已经不是可用的链接了。整个网址用 encodeURI,它专门为「保留 URL 结构」设计。
链接里的中文显示成一堆百分号怎么办?
先用解码模式还原一次,能还原说明只是显示层没解码,或者服务端把编码后的字符串又编码了一遍。如果还原出来是「中文」这种拉丁字母乱码,说明是 UTF-8 被当成 Latin-1 或 Windows-1252 读了,可以用中文转义的「先修复 UTF-8 乱码」还原。
为什么解码之后 + 号还是 + 号?
百分号编解码本身不处理 +,+ 表示空格只是 HTML 表单编码的约定。确认数据来自表单或查询串时,勾上「表单模式」再解码。
一次能处理多条参数值吗?
可以。「按行处理」默认开启,每一行独立编解码,行与行之间的换行不会被编成 %0A,适合把一列参数值批量转换。取消勾选则整段当成一个字符串处理。
emoji 为什么编出来这么长?
emoji 的码点大于 U+FFFF,UTF-8 需要 4 个字节,所以是 8 个十六进制字符、四个 %XX。这是正常的,不是工具多编了。

相关工具

中文转义中文与 \uXXXX、HTML 实体、URL 百分号编码互转 数据脱敏手机号、身份证、邮箱、银行卡、IP、姓名批量打码 JSON 格式化格式化、压缩、校验 JSON,顺便看中文转义