准确解析 · 主动规范化
URL 的含义可以不变,字节写法却已经变化。
浏览器会解析、规范化、编码并序列化 URL。这通常很方便,但当缓存键、签名、重复参数或审计日志依赖原始拼写时,每一处变化都需要看清。这里处理的是 URL 文本,不会访问它指向的网络资源。
https://User:pa%24%24@例子.test:8443/a%2Fb/c%20d?tag=red+shoes&tag=web#Top%2FSectionhttps://User:pa%24%[email protected]:8443/a%2Fb/c%20d?tag=red+shoes&tag=web#Top%2FSection主机名已显示 punycode 规范化结果。再次使用前,还要检查凭据、查询参数顺序和路径中已编码的斜杠。
URL 结构
每个分隔符都会改变解析器所处的状态。
https:决定安全语境和默认端口
User:••••@经常被日志记录或意外泄漏
xn--fsqu00a.test国际化域名会序列化为 ASCII
8443非默认端口也是 origin 的一部分
/a%2Fb/c%20d%2F 仍位于同一个路径段内
?tag=…&tag=…保持顺序的键值对
#Top%2FSection仅供客户端使用,不会随 HTTP 请求发送
把查询参数视为有序多值映射
重复参数名本身就是数据。
如果转换成普通对象,tag=red shoes 会被 tag=web 覆盖;URLSearchParams 会按顺序保留两个参数对。
tagred shoes加号按表单查询规则解码为空格tagweb同名参数的第二个值empty∅空字符串值flag∅只有键名的写法在序列化时会规范化next/billing?step=2值本身是一个嵌套 URL编码规则对照
同一个字符在不同 URL 位置可能承担不同的协议含义。
red shoesred%20shoes在表单式查询数据中也可能写成 red+shoes
C++C%2B%2B未经编码的 + 可能被解码为空格
a/ba%2Fb编码后的斜杠仍留在一个路径段内
例子.testxn--fsqu00a.test按 IDNA 规则序列化主机名
50%50%25再次编码会变成 %2525
含敏感信息的 URL 检查
能读懂,不代表适合写进日志。
用户信息
高风险分享或记录前移除用户名和密码。
查询参数中的访问令牌
高风险优先使用请求头;查询字符串会扩散到日志、历史记录等位置。
签名参数
字节敏感规范化或重排参数可能使签名失效。
Fragment 数据
仅客户端不会发送到 HTTP 服务端,但仍可能经复制链接和页面脚本泄漏。
重建前后差异
检查一次逻辑编辑实际改变了哪些字节。
这个示例只改变了最后一个字节。排序、解码、punycode 规范化或编辑任一组成部分后,都应重新检查差异。
?tag=red+shoes&tag=web&next=%2Fbilling%3Fstep%3D2?tag=red+shoes&tag=web&next=%2Fbilling%3Fstep%3D3