URL中的百分号编码

百分号编码是使URL能够使用特殊字符、国际文本和二进制数据的机制。

编码过程

过程很简单:取ASCII值(或UTF-8字节)并将其写为%XX,其中XX是十六进制。

示例:空格是ASCII 32 = 十六进制20,所以变为%20。&字符是ASCII 38 = 十六进制26,所以变为%26。%字符本身是ASCII 37 = 十六进制25,所以变为%25。

对于非ASCII字符,首先转换为UTF-8字节。€字符是UTF-8字节E2 82 AC,变为%E2%82%AC。

解码逆转过程:找到%XX序列,将十六进制转换为字节,将字节解释为UTF-8。

十六进制数字的大小写:%2F和%2f都是有效且等效的。惯例倾向于大写以保持一致性。

常见错误

当已编码的URL被重新编码时,会发生双重编码。%20变为%2520。当您不控制两个级别的编码时,会发生这种情况。症状:URL字面显示%20而不是空格。

编码不足会使应该编码的字符未编码。这会破坏URL或创建安全漏洞。始终完全编码用户输入。

在JavaScript中使用错误的函数:encodeURI()与encodeURIComponent()。记住:encodeURIComponent用于值,encodeURI用于整个URL(很少需要)。

将空格编码为+仅在查询字符串中有效,并且仅在某些上下文中。使用%20以获得通用兼容性。许多系统不接受+作为路径部分中的空格。

Unicode规范化经常被遗忘。相同的可见字符可以有不同的Unicode表示,编码方式不同。如果一致性很重要,在编码之前进行规范化。

何时编码什么

当包含用户输入时,查询参数必须始终编码。'?search=' + encodeURIComponent(userQuery)防止注入攻击和URL损坏。

URL路径需要/未编码(路径分隔符),但其他特殊字符需编码。对于像「Tom & Jerry.pdf」这样的文件名:'/files/' + encodeURIComponent(filename)。

片段标识符(#后)有不同的规则。某些应用程序期望未编码的片段,其他期望编码的。检查您平台的文档。

来自用户的完整URL应该被清理。验证协议(仅允许http/https,阻止javascript:),检查编码滥用,并考虑URL验证库。

API请求:大多数HTTP库自动处理编码。如果您手动构建URL,单独编码每个参数值,然后用&连接它们。

试用工具

URL编码/解码器

URL编码/解码器