对任意文字做URL编码或解码

对查询参数值、路径片段或整个网址做百分号编码,也可以把%XX序列还原成可读文字。支持UTF-8、表单式的+号空格,以及逐行处理。内容不会离开你的浏览器。

如何对文字做URL编码或解码

  1. 把文字、参数值或网址粘贴到输入框中。
  2. 选择编码类型。只处理单个查询参数值或路径片段时,保持组件即可;如果是一个完整地址,只需要修正其中的空格和非ASCII字符,选择完整网址;如果数据将按HTML表单提交的方式被读取,选择表单。
  3. 点击编码或解码。勾选每行一个值后,每一行会单独处理,因此可以一次转换整列参数或网址。
  4. 复制结果,或点击将结果作为输入再运行一次,例如把被编码了两次的值逐层还原。

解码带有查询字符串的完整网址时,工具还会以明文列出每个参数的名称和值,这是阅读一长串追踪链接或跳转链接最快的办法。

什么是百分号编码

网址只能包含有限的一组ASCII字符,而其中一些字符有特定用途:?开启查询字符串,&分隔参数,#开启片段,/分隔路径片段。其余内容要放进网址,就靠百分号编码:每个字符先转换成UTF-8字节,再把每个字节写成%加两位十六进制数。空格只有一个字节,所以变成%20;é有两个字节,写作%C3%A9;像😀这样的表情符号有四个字节,写作%F0%9F%98%80。汉字通常占三个字节,例如“书”会变成%E4%B9%A6。解码就是把这个过程反过来。

这些规则来自定义URI语法的标准RFC 3986第2节。它建议十六进制数字使用大写(写%3A,不写%3a),要求文字先按UTF-8转为字节,并提醒实现方不得对同一个字符串重复进行百分号编码或解码。

保留字符与非保留字符(RFC 3986)

RFC 3986把网址可以包含的字符分成两组:

  • 非保留字符:字母A–Z a–z、数字0–9以及- . _ ~。它们永远不需要编码,编码与否含义相同。
  • 保留字符:通用分隔符: / ? # [ ] @和子分隔符! $ & ' ( ) * + , ; =。它们可能承载网址的结构,所以当其中某个字符是你的数据而不是网址语法的一部分时,必须做百分号编码。

其余字符,包括空格、%本身、引号、尖括号和所有非ASCII字符,都不能原样出现在网址中,必须编码。最常见的几个如下:

字符编码后为什么重要
空格%20(表单数据中为+)网址中根本不允许出现
&%26会开启一个新的查询参数
=%3D会把参数名和参数值分开
?%3F会开启查询字符串
#%23会把其后的所有内容划为片段,而片段永远不会发送到服务器
/%2F会多出一个路径片段
+%2B在表单编码的查询字符串里会被读成空格
%%25会被当作转义序列的开头
: @%3A %40分隔协议、账号信息和主机
é%C3%A9非ASCII字符,按两个UTF-8字节编码

组件、完整网址、RFC 3986还是表单:该选哪个

同一段输入,会因为结果的去向不同而编码成不同的样子。以输入Tom & Jerry's (2024)/ü为例:

  • 组件得到Tom%20%26%20Jerry's%20(2024)%2F%C3%BC。这就是JavaScript的encodeURIComponent,除字母、数字和- _ . ! ~ * ' ( )外全部编码。适用于单个查询参数值、单个路径片段,或者要放进另一个网址参数里的网址,比如跳转目标。
  • 严格RFC 3986得到Tom%20%26%20Jerry%27s%20%282024%29%2F%C3%BC。它额外编码! ' ( ) *:RFC 3986把这几个字符列为子分隔符,而encodeURIComponent却放过了它们。当严格的解析器或请求签名方案要求完全符合RFC字符集时使用。
  • 表单得到Tom+%26+Jerry%27s+%282024%29%2F%C3%BC。它遵循WHATWG URL标准中的application/x-www-form-urlencoded格式:只有字母、数字和* - . _保持原样,空格变成+。HTML表单和URLSearchParams发送的就是这种格式。
  • 完整网址得到Tom%20&%20Jerry's%20(2024)/%C3%BC。这是encodeURI,它保留; / ? : @ & = + $ , #不动,因为它认为这些字符在完整网址里已经各司其职。只适合整理含有空格或非ASCII文字的完整地址,千万不要用来处理参数值:值里的&会悄悄开启一个新参数。

%20还是+:网址中的空格

两种约定并存。在RFC 3986的网址语法里,空格永远是%20,而+只是一个普通的加号。在浏览器用GET提交表单时使用的表单编码格式里,空格写成+,该格式对应的WHATWG解析器会先把每个+替换成空格,再做百分号解码。所以?q=a+b在表单数据解析器看来是“a b”,而路径里的/a+b则表示“a+b”。

这就是解码器提供解码时将+视为空格选项的原因。对于表单、搜索框和大多数统计工具生成的查询字符串,请勾选它;处理路径,以及加号本身有意义的值时请不要勾选,比如name+tag@example.com这样的邮箱地址,编码后是name%2Btag%40example.com。

代码中的对应写法

  • JavaScript:处理参数值用encodeURIComponent()和decodeURIComponent(),处理完整网址用encodeURI(),需要表单式+空格的查询字符串用URLSearchParams(参见MDN)。
  • Python:urllib.parse.quote()默认不编码/,空格写成%20,适合路径;quote_plus()会编码/并把空格写成+,适合表单值(参见Python文档)。
  • PHP:rawurlencode()遵循RFC 3986,空格写成%20;urlencode()则把空格写成+(参见PHP手册)。

常见的URL编码问题

重复编码:%2520而不是%20

如果网址里出现%2520、%253A之类的内容,说明有程序对已经编码过的字符串又编码了一次;%25就是编码后的百分号。先解码一次,看看结果。当解码结果里仍含有百分号序列时,本工具会给出提醒,你可以点击将结果作为输入继续解码下一层。代码层面的修复办法是:在拼接网址的那一刻,对每个值只编码一次。

“Malformed URI sequence”错误

严格的解码器会拒绝后面没有跟着两位十六进制数的%,以及不合法的UTF-8字节序列。本解码器则比较宽容:它会解码所有有效的序列,保留孤立的%,把无效字节替换成�替换字符,并告诉你发生了这些情况,这样你就能找到出错的位置,而不是什么结果都得不到。

参数值在#或&处被截断

如果某个参数到达时被截断了,说明值里含有未编码的#或&,通常是因为网址是用字符串拼接,或用“完整网址”模式编码出来的。请改用“组件”模式对值编码。

对整个网址编码后网址坏了

把一个完整网址放进“组件”模式,会把https://变成https%3A%2F%2F。只有当这个网址本身是另一个网址里的参数值时,这样才是对的。否则请只对要插入的那一部分编码,或者使用“完整网址”模式。

相关的网址工具

用UTM链接生成器生成完整的活动链接,用网址清理工具去掉追踪参数,用重定向检查工具查看一个链接经过的每一次跳转。想把脚本做成一键使用的浏览器书签,书签小程序生成器会替你做好百分号编码。如果你在工作时顺手保存RFC这类参考文档,Marqly会把它们放进同一个可搜索的资料库,详见面向开发者的Marqly。

常见问题解答

URL编码是做什么的?

它会把网址中不安全或有特殊含义的字符,按UTF-8字节逐个替换成百分号加两位十六进制数。空格变成%20,&变成%26,é变成%C3%A9。这样任何文字都能放进网址里传递,而不会被误认为网址自身的结构。

encodeURI和encodeURIComponent有什么区别?

encodeURIComponent会编码除字母、数字以及 - _ . ! ~ * ' ( ) 之外的所有字符,所以适合处理单个查询参数值或路径片段。encodeURI还会保留 ; / ? : @ & = + $ , # 不动,因为它假定你传入的是已经结构完整的网址。处理参数值请用“组件”模式,只有整个地址才用“完整网址”模式。

空格应该写成%20还是+?

两种写法在不同场景下都是对的。%20在网址的任何位置都有效;加号只在表单编码的查询字符串(application/x-www-form-urlencoded)里表示空格,HTML表单和URLSearchParams生成的就是这种格式。在路径中,加号就是普通的加号。解码来自表单的查询字符串时,请勾选“解码时将+视为空格”。

为什么我的网址里出现了%2520?

因为它被编码了两次。第一次把空格变成%20,第二次又把%本身编码成%25,于是得到%2520。RFC 3986规定,同一个字符串不应被编码或解码超过一次。先解码一次,看是否还原成%20,再解码一次即可。

可以一次编码或解码很多网址吗?

可以。每行粘贴一个值,并保持勾选“每行一个值”。每一行会单独编码或解码,换行会被保留,而不会变成%0A。

哪些字符需要编码?

凡是当作“值”而不是网址结构的一部分时,RFC 3986非保留字符集(字母、数字、连字符、句点、下划线、波浪号)之外的任何字符都必须编码。其中包括空格、非ASCII字符、%,以及 ? # & = / : @ 和 + 这类保留分隔符。

我输入的文字会被上传吗?

不会。编码、解码和查询字符串拆解都在你的浏览器里用内置的JavaScript函数完成,不会向任何服务器发送数据。

← 免费工具

首页 · Marqly