正在加载,请稍候…

URL编码详解:为什么特殊字符必须转义

了解URL为何需要编码、什么是百分号编码,以及如何使用我们的免费在线URL编码和解码工具正确进行URL编码与解码。

URL编码详解:为什么特殊字符必须转义

什么是URL编码?

URL编码(也称为百分号编码)将URL中不允许的字符转换为可以在互联网上安全传输的格式。该过程将不安全字符替换为百分号(%)后跟两个十六进制数字,表示该字符的ASCII或UTF-8代码。

每个URL必须仅由一组定义的安全字符组成。超出该集合的任何字符都必须编码。

URL编码详解:为什么特殊字符必须转义 插图

为什么URL有受限字符

URI规范(RFC 3986)将字符分为三类:

  1. 保留字符在URI中具有特殊含义:: / ? # [ ] @ ! $ & ' ( ) * + , ; =
  2. 非保留字符始终安全:A-Z a-z 0-9 - _ . ~
  3. 所有其他字符必须进行百分号编码

如果保留字符出现在查询参数值中,则必须编码。否则,解析器会将其误解为结构分隔符。

百分号编码的工作原理

空格 = 0x20 -> %20
!     = 0x21 -> %21
#     = 0x23 -> %23
&     = 0x26 -> %26
+     = 0x2B -> %2B(字面加号)
=     = 0x3D -> %3D
?     = 0x3F -> %3F
@     = 0x40 -> %40

多字节UTF-8字符被编码为多个百分号序列:

é = UTF-8 0xC3 0xA9 -> %C3%A9
中 = UTF-8 0xE4 0xB8 0xAD -> %E4%B8%AD

URL编码详解:为什么特殊字符必须转义 插图

URL编码与表单编码

有两种相关但不同的编码方案。百分号编码(RFC 3986)将空格转换为%20,用于路径段和严格的URI一致性。application/x-www-form-urlencoded将空格转换为+,用于HTML表单提交。它们的编码规则略有不同。

// 百分号编码(标准)
encodeURIComponent('hello world') // 'hello%20world'

// 表单编码(空格为+)
new URLSearchParams({ q: 'hello world' }).toString() // 'q=hello+world'

JavaScript URL编码函数

JavaScript有四个用于URL编码和解码的函数:

函数 编码内容 使用场景
encodeURI 除未保留字符和结构字符外的所有字符 编码完整URL
encodeURIComponent 除未保留字符外的所有字符 编码查询参数、路径段
decodeURI 反转encodeURI 解码完整URL
decodeURIComponent 反转encodeURIComponent 解码URL组件
// 编码完整URL - 保留结构字符
encodeURI('https://example.com/path?q=hello world')
// 'https://example.com/path?q=hello%20world'

// 编码查询参数值
encodeURIComponent('hello world & more')
// 'hello%20world%20%26%20more'

// 解码
decodeURIComponent('hello%20world')  // 'hello world'

URL编码详解:为什么特殊字符必须转义 插图

常见URL编码示例

Web开发中最常编码的字符有:空格变为%20,井号变为%23(在查询值中使用%23,因为#是片段分隔符),与号变为%26(在查询值中使用%26,因为&分隔参数),加号变为%2B(用于字面加号),正斜杠变为%2F(用于路径段中的字面斜杠),等号变为%3D(在参数值内部)。

URL结构及编码应用位置

https://example.com:8080/path?key=value&foo=bar#section

每个部分有不同的编码规则。路径段应对除未保留字符和斜杠分隔符之外的所有内容进行编码。查询参数应对与号、等号、加号、百分号等进行编码。片段遵循与查询编码类似的规则。

国际化URL

现代浏览器以Unicode形式显示国际化域名和路径,但在传输时进行编码。例如,路径中包含中文字符的URL在浏览器中会正常显示,但传输时作为百分号编码的UTF-8字节。域名使用Punycode(xn--)编码处理非ASCII字符。

-> 试试 URL编码/解码工具