← 返回首页

URL 编码完全指南

什么是 URL 编码?

URL 编码(也叫百分号编码,Percent-encoding)是一种将 URL 中的非安全字符转换为特定格式的机制。它使用百分号 % 后跟两位十六进制数来表示一个字节,例如空格被编码为 %20,中文字符"中"被编码为 %E4%B8%AD

URL 编码的目的是确保 URL 中的特殊字符不会与 URL 的语法结构产生冲突,同时保证数据能在网络中安全传输。

为什么需要 URL 编码?

URL 的规范(RFC 3986)定义了 URL 中允许使用的字符集。URL 只允许包含以下字符:

所有不在上述列表中的字符(包括中文、日文、空格、引号等)都必须进行 URL 编码后才能在 URL 中安全使用。

常见的需要编码的场景包括:

URL 编码的原理

URL 编码的核心规则非常简单:

  1. 将字符按照指定的字符编码(通常是 UTF-8)转换为字节序列
  2. 每个字节用一个百分号 % 后跟两位大写十六进制数表示

ASCII 字符的编码

对于 ASCII 字符(码值 0-127),直接取其十六进制值:

空格    → %20
!       → %21
"       → %22
#       → %23
$       → %24
%       → %25
&      → %26
'       → %27
(       → %28
)       → %29
+       → %2B
,       → %2C
/       → %2F
:       → %3A
;       → %3B
=       → %3D
?       → %3F
@       → %40

中文字符的编码(UTF-8)

中文字符在 UTF-8 编码下通常占用 3 个字节。例如:

中 → UTF-8 字节: E4 B8 AD → %E4%B8%AD
文 → UTF-8 字节: E6 96 87 → %E6%96%87
编 → UTF-8 字节: E7 BC 96 → %E7%BC%96
码 → UTF-8 字节: E7 A0 81 → %E7%A0%81
你 → UTF-8 字节: E4 BD A0 → %E4%BD%A0
好 → UTF-8 字节: E5 A5 BD → %E5%A5%BD

完整的"你好"编码后为 %E4%BD%A0%E5%A5%BD

空格的两种编码方式

空格可以编码为 %20+。两者的使用场景不同:

注意:+ 在 URL 编码中代表空格,所以如果原始数据包含真实的 + 号,需要编码为 %2B

JavaScript 中的 URL 编码函数

encodeURIComponent()

最常用的 URL 编码函数,对字符串进行完整编码。它会编码所有非字母数字字符以及 - _ . ! ~ * ' ( ) 之外的字符。

encodeURIComponent("hello world")
// "hello%20world"

encodeURIComponent("你好世界")
// "%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C"

encodeURIComponent("https://example.com")
// "https%3A%2F%2Fexample.com"

encodeURIComponent("name=张三&age=28")
// "name%3D%E5%BC%A0%E4%B8%89%26age%3D28"

encodeURIComponent("a/b/c?d=e")
// "a%2Fb%2Fc%3Fd%3De"

使用场景:编码 URL 的查询参数值、POST 请求体中的数据。

encodeURI()

encodeURIComponent 类似,但不编码 URL 中的保留字符(如 ://?=&/ 等),因为这些字符是 URL 结构的一部分。

encodeURI("https://example.com/路径/查询")
// "https://example.com/%E8%B7%AF%E5%BE%84/%E6%9F%A5%E8%AF%A2"

encodeURI("https://example.com/search?q=你好")
// "https://example.com/search?q=%E4%BD%A0%E5%A5%BD"

使用场景:编码完整的 URL 地址。注意:不要用 encodeURI 编码查询参数值,因为 =& 不会被编码。

两者的关键区别

// 编码斜杠 /
encodeURIComponent("/foo/bar")  // "%2Ffoo%2Fbar"
encodeURI("/foo/bar")           // "/foo/bar"(不编码)

// 编码问号 ?
encodeURIComponent("?q=test")   // "%3Fq%3Dtest"
encodeURI("?q=test")            // "?q=test"(不编码)

// 编码等号 =
encodeURIComponent("key=value") // "key%3Dvalue"
encodeURI("key=value")          // "key=value"(不编码)

// 编码与号 &
encodeURIComponent("a&b")       // "a%26b"
encodeURI("a&b")                // "a%26b"(& 会被编码)

简单记忆:encodeURI 用来编码整个 URL(保留 URL 结构字符),encodeURIComponent 用来编码 URL 的某个参数值(几乎全部编码)。

解码函数

decodeURIComponent("%E4%BD%A0%E5%A5%BD")
// "你好"

decodeURIComponent("hello%20world")
// "hello world"

decodeURI("https://example.com/%E8%B7%AF%E5%BE%84")
// "https://example.com/路径"

其他语言中的 URL 编码

Python

from urllib.parse import quote, quote_plus, unquote

quote("你好世界")
# '%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C'

quote_plus("hello world")
# 'hello+world'

unquote('%E4%BD%A0%E5%A5%BD')
# '你好'

Java

import java.net.URLEncoder;
import java.net.URLDecoder;

URLEncoder.encode("你好世界", "UTF-8")
// "%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C"

URLDecoder.decode("%E4%BD%A0%E5%A5%BD", "UTF-8")
// "你好"

常见 URL 编码问题

1. 中文参数乱码

中文乱码通常由编码不一致引起。发送端使用 UTF-8 编码,但接收端使用 GBK/GB2312 解码,就会出现乱码。

解决方案:确保发送和接收双方使用相同的字符编码(推荐 UTF-8)。前端使用 encodeURIComponent,后端使用 UTF-8 解码。

2. 双重编码问题

如果对已经编码过的字符串再次编码,会导致出现 %25 前缀(因为 % 本身被编码为 %25):

// 第一次编码
encodeURIComponent("你好")  // "%E4%BD%A0%E5%A5%BD"

// 第二次编码(错误!)
encodeURIComponent("%E4%BD%A0%E5%A5%BD")  // "%25E4%25BD%25A0%25E5%25A5%25BD"

避免在框架已经自动编码的情况下手动再次编码。

3. + 号和空格混淆

在查询字符串中,+ 会被解码为空格。如果你的原始数据包含 + 号:

// 原始数据: "1+2=3"
// 错误编码: encodeURIComponent("1+2=3") → "1%2B2%3D3"(正确)
// 如果直接放到查询字符串中被替换为空格: "1 2=3"(错误)

4. URL 长度限制

URL 编码会使中文字符膨胀为 3 倍长度(1 个中文字符 -> 9 个字符的编码)。不同浏览器和服务器对 URL 长度有限制:

如果 URL 可能超长,建议使用 POST 请求代替 GET 请求传递数据。

URL 编码速查表

字符    编码       字符    编码       字符    编码
空格    %20        <       %3C        @       %40
!       %21        =       %3D        [       %5B
"       %22        >       %3E        \       %5C
#       %23        ?       %3F        ]       %5D
$       %24        @       %40        ^       %5E
%       %25        [       %5B        _       %5F(不编码)
&       %26        \       %5C        `       %60
'       %27        ]       %5D        {       %7B
(       %28        ^       %5E        |       %7C
)       %29        _       %5F        }       %7D
*       %2A(不编码)  `       %60        ~       %7E(不编码)
+       %2B        {       %7B
,       %2C        |       %7C
/       %2F        }       %7D
:       %3A

在线 URL 编码工具

手动进行 URL 编码和解码容易出错,特别是处理中文和特殊字符时。使用我们的 在线 URL 编码解码工具,只需粘贴文本即可一键编码或解码,支持批量处理,所有计算在浏览器本地完成,数据不会上传到服务器。

总结

URL 编码是 Web 开发中不可或缺的基础知识。理解 URL 编码的原理和 UTF-8 编码规则,可以帮助你避免中文乱码、双重编码、+号混淆等常见问题。在前端开发中,记住 encodeURIComponent 用于编码参数值,encodeURI 用于编码完整 URL。在后端开发中,确保解码时使用正确的字符编码。

更多前端开发工具,欢迎访问 EITools 在线工具箱