URL 编码与解码

编码单个值、编码整条 URL,或反过来解码。

查询参数

这个工具能做什么

URL 只能包含有限的一组 ASCII 字符。其它任何东西——空格、中文、&、=、?、# 和大部分标点——都必须先百分号编码成 %XX 字节,才能安全地放进链接、表单提交或 API 调用。本页双向完成这种编码,而且不同于多数编码器,它还会把结果拆开:粘贴任意 URL 或查询字符串,参数就会以解码后的键值表呈现,一眼读懂一条追踪链接或 OAuth 跳转。

文本按 UTF-8 处理,所以「中文」会变成 %E4%B8%AD%E6%96%87,与浏览器和服务器的预期完全一致。解码是宽容的:不构成合法转义的孤立 % 会原样保留而不是抛错,解码表单数据时 + 会当作空格。

编码单个值 vs 编码整条 URL

「编码组件」就是 JavaScript 的 encodeURIComponent:除字母、数字和 -_.!~*'() 之外全部转义。用于放进查询参数、路径段或表单字段的单个值。「编码 URL」是 encodeURI:保留结构字符 :/?#[]@!$&'()*+,;= 不动,只转义空格和非 ASCII 文本,让一条完整地址仍是合法地址。用错是经典 bug——对整条 URL 用 encodeURIComponent 会把每个 / 变成 %2F 从而弄坏链接,而对含 & 的值用 encodeURI 会悄悄把它拆成两个参数。

「空格用 +」选项在 %20(RFC 3986,URL 中使用)与 +(application/x-www-form-urlencoded,HTML 表单体和许多旧式查询串使用)之间切换。两种在这里都能正确解码;编码时按目标系统的预期选择。

常见错误

重复编码:对已编码的值再编码会把 %20 变成 %2520,服务器看到的是字面的 %20。如果解码结果里还有 %XX 序列,就再解一次。忘记对值里的 & 或 # 编码会截断参数。对整条 URL 用 encodeURIComponent 会破坏协议头和斜杠。客户端与服务器对 + 和 %20 的约定不一致,会让用户名里出现加号。最后,百分号编码不是加密也不是混淆——解码后完全可读,绝不要靠它隐藏令牌;需要不透明传输时通常用 Base64,但它同样可以轻易还原。

背景:百分号编码从哪里来

百分号编码随第一份 URL 规范 RFC 1738(1994,Tim Berners-Lee 等人撰写)一同定义,并在 RFC 3986(2005)中完善,后者是现行的 URI 语法标准。% 转义机制早于 UTF-8 的普及,所以老系统有时按 Latin-1 或 Shift-JIS 编码字节,按 UTF-8 解码时就会出现乱码——HTML5 的 URL Standard(WHATWG)最终规定新编码一律使用 UTF-8。「空格用 +」的约定来自独立的 HTML 表单规范而非 URL 标准,这就是今天两种空格编码并存的历史原因。

应用领域

手工拼接 API 请求(搜索词、筛选条件、回调地址),调试广告平台的追踪链接(utm_source、gclid、fbclid),阅读 OAuth 与 SSO 跳转(redirect_uri、state、scope),构造带主题和正文的 mailto: 与 tel: 链接,分享含中文或日文路径的链接,以及检查以表单格式发送的 Webhook 负载。参数表特别适合把工单里的长 URL 粘进来,看清到底请求了什么。查询串里的值经常是 JSON 或 Base64——先在这里解码,再把值粘到对应的工具。

常见问题

encodeURI 和 encodeURIComponent 有什么区别?

encodeURIComponent 除未保留字符外全部转义,用于单个值;encodeURI 保留 URL 结构字符(/ ? & = # :),用于完整地址。绝不要对整条 URL 用 encodeURIComponent。

空格应该是 %20 还是 +?

URL 中用 %20(RFC 3986);+ 只用于 application/x-www-form-urlencoded 表单体和遵循 HTML 表单约定的查询串。这里两种都解码为空格。

为什么解码结果里有 %2520?

这个值被编码了两次。再解码一次即可得到原文。

支持中文和 emoji 吗?

支持。文本按 UTF-8 字节编码,每个汉字变成三个 %XX,多数 emoji 变成四个。

会有数据发送到服务器吗?

不会。编码、解码和参数解析全部在浏览器中完成。