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编码/解码器