URL 编码:您需要知道的一切
· 12分钟阅读
目录
理解 URL 编码
URL 编码,也称为百分号编码,是确保互联网上可靠数据传输的基本机制。它将 URL 中不允许的字符转换为可以被网络浏览器、服务器和其他互联网基础设施安全传输和解释的格式。
从本质上讲,URL 编码解决了一个简单的问题:URL 只能包含 ASCII 字符集中的有限字符集。当您需要包含此集合之外的字符时——无论是特殊符号、空格还是非拉丁字符——它们必须被编码为通用识别的格式。
编码过程将有问题的字符替换为百分号(%),后跟两个十六进制数字,表示字符的 ASCII 或 UTF-8 代码。这确保了 URL 的每个组成部分都完全按照预期传输,不会出现误解或数据丢失。
快速提示:使用我们的 URL 编码器和解码器工具,无需编写代码即可立即编码或解码任何 URL 字符串。
为什么需要 URL 编码
URL 编码的必要性源于互联网的原始设计约束以及 RFC 3986 中定义的 URL 规范。URL 被设计为使用有限的字符集,以确保跨不同系统、协议和地理区域的兼容性。
如果没有 URL 编码,将会出现几个关键问题:
- URL 结构的歧义:特殊字符如
?、&和#在 URL 中具有特定含义。如果这些字符在您的数据中出现而没有编码,它们将被解释为 URL 分隔符而不是内容。 - 字符集不兼容:不同的系统可能会以不同的方式解释相同的字节序列,导致数据损坏或请求失败。
- 协议违规:HTTP 和其他互联网协议期望 URL 符合特定的格式规则。未编码的字符可能导致协议错误。
- 安全漏洞:未编码的特殊字符可能被利用进行注入攻击或绕过安全过滤器。
考虑在 URL 中搜索"cats & dogs"的查询。如果没有编码,& 符号将被解释为参数分隔符,可能会将您的查询分解为两个单独的参数。URL 编码将其转换为 cats%20%26%20dogs,保留了预期的含义。
ASCII 限制
URL 建立在 ASCII 字符集上,该字符集仅包含 128 个字符。其中,只有一个子集——称为"未保留字符"——可以在 URL 中出现而无需编码。这些未保留字符包括:
- 大写和小写字母(A-Z,a-z)
- 十进制数字(0-9)
- 连字符(
-)、句点(.)、下划线(_)和波浪号(~)
其他所有内容都需要编码,以确保在互联网上正确传输和解释。
URL 编码的工作原理
URL 编码过程遵循一个简单的算法,将字符转换为其百分号编码的等效形式。理解这个过程可以帮助您排查编码问题并编写更健壮的 Web 应用程序。
编码算法
当字符需要编码时,过程如下:
- 识别字符:根据 URL 组件和编码规则确定哪个字符需要编码。
- 获取字节值:使用 UTF-8 编码(或基本字符的 ASCII)将字符转换为其字节表示。
- 转换为十六进制:将每个字节表示为两个十六进制数字。
- 添加百分号前缀:在每个十六进制对前面加上百分号(
%)。
例如,空格字符的 ASCII 值为 32(十进制)或 20(十六进制)。编码后,它变成 %20。@ 符号(@)的 ASCII 值为 64(十进制)或 40(十六进制),因此编码为 %40。
UTF-8 多字节编码
对于 ASCII 范围之外的字符,UTF-8 编码会产生多个字节,每个字节都会被百分号编码。表情符号"😀"(咧嘴笑脸)在 UTF-8 中编码为四个字节:F0 9F 98 80。在 URL 中,这变成 %F0%9F%98%80。
这种多字节编码确保来自任何语言或符号集的字符都可以在 URL 中安全传输,使网络真正国际化。
专业提示:在调试 URL 编码问题时,使用浏览器的开发者工具检查实际发送的编码 URL。网络选项卡显示原始编码请求,可以揭示编码问题。
需要编码的字符
并非所有字符在所有上下文中都需要编码,但了解哪些字符需要编码以及何时编码对于构建可靠的 Web 应用程序至关重要。编码要求因您正在处理的 URL 部分而异。
保留字符
保留字符在 URL 语法中具有特殊含义,当用作数据而不是分隔符时必须编码。这些字符包括:
| 字符 | 在 URL 中的用途 | 编码形式 |
|---|---|---|
: |
分隔方案和主机,端口分隔符 | %3A |
/ |
路径段分隔符 | %2F |
? |
标记查询字符串的开始 | %3F |
# |
标记片段标识符的开始 | %23 |
[ ] |
IPv6 地址分隔符 | %5B %5D |
@ |
将凭据与主机分隔 | %40 |
! $ & ' ( ) * + , ; = |
用于各种目的的子分隔符 | %21 %24 %26 %27 %28 %29 %2A %2B %2C %3B %3D |
不安全字符
某些字符被认为是不安全的,因为它们在传输过程中可能被修改或误解。这些字符始终需要编码:
| 字符 | 为什么不安全 | 编码形式 |
|---|---|---|
| 空格 | 可能被删除或转换为 + |
%20 |
" |
用于在 HTML 中分隔 URL | %22 |
< > |
用于 HTML 标签,可能被过滤 | %3C %3E |
% |
编码分隔符本身 | %25 |
\ |
某些系统上的路径分隔符 | %5C |
^ ` { } | |
不是普遍支持的 | %5E %60 %7B %7D %7C |
上下文相关编码
编码要求因您正在处理的 URL 组件而异。在一种上下文中安全的字符在另一种上下文中可能需要编码:
- 路径段:正斜杠分隔路径段,因此除非它们是段名称本身的一部分,否则不应编码。
- 查询参数:& 符号和等号具有特殊含义,因此在参数值中出现时必须编码。
- 片段标识符:允许大多数字符,但仍建议编码以保持一致性。
URL 编码的常见用例
URL 编码出现在许多实际场景中。了解这些用例可以帮助您识别何时以及如何在自己的项目中应用编码。
搜索查询
搜索引擎严重依赖 URL 编码来处理用户查询。当您在 Google 上搜索"如何烤蛋糕?"时,URL 变成类似这样:
https://www.google.com/search?q=how+to+bake+a+cake%3F
请注意,空格被编码为加号(查询字符串中空格的替代编码),问号被编码为 %3F,以将其与查询字符串分隔符区分开来。
表单提交
当使用 GET 方法提交 HTML 表单时,表单数据被编码并附加到 URL。考虑一个带有用户名和密码字段的登录表单:
https://example.com/login?username=john.doe%40example.com&password=P%40ssw0rd%21
电子邮件地址和密码中的特殊字符被正确编码,以防止解释问题。
安全提示:切勿在 URL 参数中发送密码等敏感数据。此示例仅用于说明。始终使用带有 HTTPS 的 POST 请求进行身份验证。
API 请求
RESTful API 通常在需要编码的 URL 中包含参数。在过滤结果或传递复杂数据结构时,正确的编码可确保 API 接收到您想要的内容:
https://api.example.com/users?filter=created_at>2024-01-01&sort=-name
过滤器参数中的大于号必须编码为 %3E,以防止与 HTML 实体或其他解释混淆。
文件下载
在提供非 ASCII 名称的文件时,URL 编码可确保文件名正确传输:
https://example.com/downloads/Pr%C3%A9sentation%202024.pdf
"Présentation"中的重音"é"被编码为 %C3%A9(其 UTF-8 表示),允许全球用户下载文件,无论其系统的字符编码如何。
社交媒体分享
社交媒体平台在分享带有预填文本的链接时使用 URL 编码。Twitter 分享链接可能如下所示:
https://twitter.com/intent/tweet?text=Check%20out%20this%20article%21&url=https%3A%2F%2Fexample.com%2Farticle
推文文本和正在分享的 URL 都被编码,以确保